Page 1 of 1

Collection was modified; enumeration operation may not execu

Posted: Tue Aug 01, 2006 9:09 pm
by 9639856
Hello,

I'm getting the following exception when using TChart (2.0.2306.26231) in my project:

System.InvalidOperationException: Collection was modified

This exception occurs when I try to manipulate the TChart object in a method
that runs in a thread. It's a loop that plot's data in a polar graph.
I tried to catch the exception (try... catch... end try) but it was useless.
It's appear to be the same problem of the topics:
http://www.teechart.net/support/viewtop ... n+modified
http://www.teechart.net/support/viewtop ... n+modified

Also I need to know how can I draw through the loop and minimize the 'appear' and 'disapear' effect.

The code is the following (it's a simple form, to reproduce more quickly set the priority of the thread to the highest and the sleepTime to the minimum).

Thanks in advance.


Imports Steema.TeeChart
Public Class Form1

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "



'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents TChart1 As Steema.TeeChart.TChart
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Button3 As System.Windows.Forms.Button
Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.TChart1 = New Steema.TeeChart.TChart
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Button3 = New System.Windows.Forms.Button
Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown
Me.Label1 = New System.Windows.Forms.Label
Me.Label2 = New System.Windows.Forms.Label
Me.ComboBox1 = New System.Windows.Forms.ComboBox
CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'TChart1
'
'
'TChart1.Aspect
'
Me.TChart1.Aspect.ElevationFloat = 345
Me.TChart1.Aspect.RotationFloat = 345
Me.TChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
Me.TChart1.Aspect.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit
Me.TChart1.Aspect.View3D = False
'
'TChart1.Axes
'
'
'TChart1.Axes.Bottom
'
Me.TChart1.Axes.Bottom.Automatic = True
'
'TChart1.Axes.Bottom.Grid
'
Me.TChart1.Axes.Bottom.Grid.ZPosition = 0
'
'TChart1.Axes.Bottom.Labels
'
'
'TChart1.Axes.Bottom.Labels.Font
'
'
'TChart1.Axes.Bottom.Labels.Font.Shadow
'
Me.TChart1.Axes.Bottom.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.Bottom.Labels.Shadow
'
Me.TChart1.Axes.Bottom.Labels.Shadow.Visible = False
'
'TChart1.Axes.Bottom.Title
'
'
'TChart1.Axes.Bottom.Title.Font
'
'
'TChart1.Axes.Bottom.Title.Font.Shadow
'
Me.TChart1.Axes.Bottom.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.Bottom.Title.Shadow
'
Me.TChart1.Axes.Bottom.Title.Shadow.Visible = False
Me.TChart1.Axes.Bottom.Visible = False
'
'TChart1.Axes.Depth
'
Me.TChart1.Axes.Depth.Automatic = True
'
'TChart1.Axes.Depth.Grid
'
Me.TChart1.Axes.Depth.Grid.ZPosition = 0
'
'TChart1.Axes.Depth.Labels
'
'
'TChart1.Axes.Depth.Labels.Font
'
'
'TChart1.Axes.Depth.Labels.Font.Shadow
'
Me.TChart1.Axes.Depth.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.Depth.Labels.Shadow
'
Me.TChart1.Axes.Depth.Labels.Shadow.Visible = False
'
'TChart1.Axes.Depth.Title
'
'
'TChart1.Axes.Depth.Title.Font
'
'
'TChart1.Axes.Depth.Title.Font.Shadow
'
Me.TChart1.Axes.Depth.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.Depth.Title.Shadow
'
Me.TChart1.Axes.Depth.Title.Shadow.Visible = False
'
'TChart1.Axes.DepthTop
'
Me.TChart1.Axes.DepthTop.Automatic = True
'
'TChart1.Axes.DepthTop.Grid
'
Me.TChart1.Axes.DepthTop.Grid.ZPosition = 0
'
'TChart1.Axes.DepthTop.Labels
'
'
'TChart1.Axes.DepthTop.Labels.Font
'
'
'TChart1.Axes.DepthTop.Labels.Font.Shadow
'
Me.TChart1.Axes.DepthTop.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.DepthTop.Labels.Shadow
'
Me.TChart1.Axes.DepthTop.Labels.Shadow.Visible = False
'
'TChart1.Axes.DepthTop.Title
'
'
'TChart1.Axes.DepthTop.Title.Font
'
'
'TChart1.Axes.DepthTop.Title.Font.Shadow
'
Me.TChart1.Axes.DepthTop.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.DepthTop.Title.Shadow
'
Me.TChart1.Axes.DepthTop.Title.Shadow.Visible = False
'
'TChart1.Axes.Left
'
Me.TChart1.Axes.Left.Automatic = True
'
'TChart1.Axes.Left.Grid
'
Me.TChart1.Axes.Left.Grid.ZPosition = 0
'
'TChart1.Axes.Left.Labels
'
'
'TChart1.Axes.Left.Labels.Font
'
'
'TChart1.Axes.Left.Labels.Font.Shadow
'
Me.TChart1.Axes.Left.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.Left.Labels.Shadow
'
Me.TChart1.Axes.Left.Labels.Shadow.Visible = False
'
'TChart1.Axes.Left.Title
'
'
'TChart1.Axes.Left.Title.Font
'
'
'TChart1.Axes.Left.Title.Font.Shadow
'
Me.TChart1.Axes.Left.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.Left.Title.Shadow
'
Me.TChart1.Axes.Left.Title.Shadow.Visible = False
Me.TChart1.Axes.Left.Visible = False
'
'TChart1.Axes.Right
'
Me.TChart1.Axes.Right.Automatic = True
'
'TChart1.Axes.Right.Grid
'
Me.TChart1.Axes.Right.Grid.ZPosition = 0
'
'TChart1.Axes.Right.Labels
'
'
'TChart1.Axes.Right.Labels.Font
'
'
'TChart1.Axes.Right.Labels.Font.Shadow
'
Me.TChart1.Axes.Right.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.Right.Labels.Shadow
'
Me.TChart1.Axes.Right.Labels.Shadow.Visible = False
'
'TChart1.Axes.Right.Title
'
'
'TChart1.Axes.Right.Title.Font
'
'
'TChart1.Axes.Right.Title.Font.Shadow
'
Me.TChart1.Axes.Right.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.Right.Title.Shadow
'
Me.TChart1.Axes.Right.Title.Shadow.Visible = False
Me.TChart1.Axes.Right.Visible = False
'
'TChart1.Axes.Top
'
Me.TChart1.Axes.Top.Automatic = True
'
'TChart1.Axes.Top.Grid
'
Me.TChart1.Axes.Top.Grid.ZPosition = 0
'
'TChart1.Axes.Top.Labels
'
'
'TChart1.Axes.Top.Labels.Font
'
'
'TChart1.Axes.Top.Labels.Font.Shadow
'
Me.TChart1.Axes.Top.Labels.Font.Shadow.Visible = False
'
'TChart1.Axes.Top.Labels.Shadow
'
Me.TChart1.Axes.Top.Labels.Shadow.Visible = False
'
'TChart1.Axes.Top.Title
'
'
'TChart1.Axes.Top.Title.Font
'
'
'TChart1.Axes.Top.Title.Font.Shadow
'
Me.TChart1.Axes.Top.Title.Font.Shadow.Visible = False
'
'TChart1.Axes.Top.Title.Shadow
'
Me.TChart1.Axes.Top.Title.Shadow.Visible = False
Me.TChart1.Axes.Top.Visible = False
Me.TChart1.Axes.Visible = False
'
'TChart1.Footer
'
'
'TChart1.Footer.Font
'
'
'TChart1.Footer.Font.Shadow
'
Me.TChart1.Footer.Font.Shadow.Visible = False
'
'TChart1.Footer.Shadow
'
Me.TChart1.Footer.Shadow.Visible = False
'
'TChart1.Header
'
'
'TChart1.Header.Font
'
'
'TChart1.Header.Font.Shadow
'
Me.TChart1.Header.Font.Shadow.Visible = False
Me.TChart1.Header.Lines = New String() {"TeeChart"}
'
'TChart1.Header.Shadow
'
Me.TChart1.Header.Shadow.Visible = False
'
'TChart1.Legend
'
'
'TChart1.Legend.Font
'
'
'TChart1.Legend.Font.Shadow
'
Me.TChart1.Legend.Font.Shadow.Visible = False
'
'TChart1.Legend.Title
'
'
'TChart1.Legend.Title.Font
'
Me.TChart1.Legend.Title.Font.Bold = True
'
'TChart1.Legend.Title.Font.Shadow
'
Me.TChart1.Legend.Title.Font.Shadow.Visible = False
'
'TChart1.Legend.Title.Pen
'
Me.TChart1.Legend.Title.Pen.Visible = False
'
'TChart1.Legend.Title.Shadow
'
Me.TChart1.Legend.Title.Shadow.Visible = False
Me.TChart1.Location = New System.Drawing.Point(6, 6)
Me.TChart1.Name = "TChart1"
'
'TChart1.Panel
'
'
'TChart1.Panel.Shadow
'
Me.TChart1.Panel.Shadow.Visible = False
Me.TChart1.Size = New System.Drawing.Size(704, 338)
'
'TChart1.SubFooter
'
'
'TChart1.SubFooter.Font
'
'
'TChart1.SubFooter.Font.Shadow
'
Me.TChart1.SubFooter.Font.Shadow.Visible = False
'
'TChart1.SubFooter.Shadow
'
Me.TChart1.SubFooter.Shadow.Visible = False
'
'TChart1.SubHeader
'
'
'TChart1.SubHeader.Font
'
'
'TChart1.SubHeader.Font.Shadow
'
Me.TChart1.SubHeader.Font.Shadow.Visible = False
'
'TChart1.SubHeader.Shadow
'
Me.TChart1.SubHeader.Shadow.Visible = False
Me.TChart1.TabIndex = 0
'
'TChart1.Walls
'
'
'TChart1.Walls.Back
'
Me.TChart1.Walls.Back.AutoHide = False
'
'TChart1.Walls.Back.Shadow
'
Me.TChart1.Walls.Back.Shadow.Visible = False
'
'TChart1.Walls.Bottom
'
Me.TChart1.Walls.Bottom.AutoHide = False
'
'TChart1.Walls.Bottom.Shadow
'
Me.TChart1.Walls.Bottom.Shadow.Visible = False
'
'TChart1.Walls.Left
'
Me.TChart1.Walls.Left.AutoHide = False
'
'TChart1.Walls.Left.Shadow
'
Me.TChart1.Walls.Left.Shadow.Visible = False
'
'TChart1.Walls.Right
'
Me.TChart1.Walls.Right.AutoHide = False
'
'TChart1.Walls.Right.Shadow
'
Me.TChart1.Walls.Right.Shadow.Visible = False
Me.TChart1.Walls.Visible = False
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(454, 350)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(124, 36)
Me.Button1.TabIndex = 1
Me.Button1.Text = "wihtout thread"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(322, 350)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(124, 36)
Me.Button2.TabIndex = 1
Me.Button2.Text = "with thread"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(586, 350)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(124, 36)
Me.Button3.TabIndex = 1
Me.Button3.Text = "stop"
'
'NumericUpDown1
'
Me.NumericUpDown1.Location = New System.Drawing.Point(176, 350)
Me.NumericUpDown1.Maximum = New Decimal(New Integer() {10000, 0, 0, 0})
Me.NumericUpDown1.Name = "NumericUpDown1"
Me.NumericUpDown1.Size = New System.Drawing.Size(126, 20)
Me.NumericUpDown1.TabIndex = 2
Me.NumericUpDown1.Value = New Decimal(New Integer() {1000, 0, 0, 0})
'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Location = New System.Drawing.Point(78, 354)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(94, 16)
Me.Label1.TabIndex = 3
Me.Label1.Text = "threadSleep (ms):"
'
'Label2
'
Me.Label2.AutoSize = True
Me.Label2.Location = New System.Drawing.Point(80, 376)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(75, 16)
Me.Label2.TabIndex = 4
Me.Label2.Text = "threadPriority:"
'
'ComboBox1
'
Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.ComboBox1.Location = New System.Drawing.Point(176, 374)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(126, 21)
Me.ComboBox1.TabIndex = 5
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(720, 406)
Me.Controls.Add(Me.ComboBox1)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.NumericUpDown1)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.TChart1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button3)
Me.Name = "Form1"
Me.Text = "Form1"
CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)

End Sub

#End Region

Private isactive As Boolean
Private p As plotter
Private t As Threading.Thread
Private useDoEvents As Boolean

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

Me.TChart1.Aspect.View3D = False
p = New plotter(Me.TChart1)
End Sub

Private Sub playGraph()
Do While Me.isactive
p.plot()
Threading.Thread.CurrentThread.Sleep(Me.NumericUpDown1.Value)
If Me.useDoEvents Then
Application.DoEvents()
End If
Loop
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Me.isactive = False
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.useDoEvents = False
Me.isactive = True
If Me.t Is Nothing Then
Me.t = New Threading.Thread(AddressOf Me.playGraph)
t.Priority = Me.ComboBox1.SelectedItem
Me.t.Start()
ElseIf Me.t.ThreadState = Threading.ThreadState.Stopped Then
Me.t = New Threading.Thread(AddressOf Me.playGraph)
t.Priority = Me.ComboBox1.SelectedItem
Me.t.Start()
ElseIf Me.t.ThreadState = Threading.ThreadState.Suspended Then
t.Priority = Me.ComboBox1.SelectedItem
Me.t.Resume()
End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.isactive = True
Me.useDoEvents = True
Me.playGraph()
End Sub

Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
Me.isactive = False
End Sub

Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click

End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.ComboBox1.Items.Clear()
Me.ComboBox1.Items.Add(Threading.ThreadPriority.Lowest)
Me.ComboBox1.Items.Add(Threading.ThreadPriority.BelowNormal)
Me.ComboBox1.Items.Add(Threading.ThreadPriority.Normal)
Me.ComboBox1.Items.Add(Threading.ThreadPriority.AboveNormal)
Me.ComboBox1.Items.Add(Threading.ThreadPriority.Highest)
Me.ComboBox1.SelectedIndex = 2


End Sub
End Class

Public Class plotter
Private varTChart As TChart

Public Sub New(ByVal aTchart As TChart)
Me.varTChart = aTchart
End Sub

Public Sub plot()
Dim r As New Random

createSeries()
Me.varTChart.Series(0).Add(r.Next(0, 360), r.Next(0, 30), "")
Me.varTChart.Series(1).Add(r.Next(0, 360), r.Next(0, 30), "")
Me.varTChart.Series(2).Add(r.Next(0, 360), r.Next(0, 30), "")
Me.varTChart.Series(3).Add(r.Next(1, 360), r.Next(0, 30), "")
Me.varTChart.Series(4).Add(r.Next(1, 360), r.Next(0, 30), "")
Me.varTChart.Series(5).Add(r.Next(1, 360), r.Next(0, 30), "")
End Sub

Private Sub createSeries()
' If Me.varTChart.Series.Count = 0 Then
Dim serie As Styles.Polar
Me.varTChart.Series.RemoveAllSeries()
For i As Integer = 0 To 5
serie = New Styles.Polar
serie.Circled = True
serie.AngleIncrement = 30
serie.CloseCircle = False
serie.Pointer.Pen.Width = 1
serie.Pen.Width = 2
serie.CircleLabels = True
serie.ShowInLegend = False
Me.varTChart.Series.Add(serie)
Me.varTChart.Series(i).Add(30, 0, "")
Next
'Else
'For i As Integer = 0 To 5
' If Me.varTChart.Series(i).ValuesLists.Count > 0 Then
' Me.varTChart.Series(i).Clear()
' Me.varTChart.Series(i).Add(30, 0, "")
' End If
'Next
'Me.varTChart.Refresh()
'End If
End Sub
End Class
[/url]

Posted: Wed Aug 02, 2006 10:09 am
by Chris
Hello,

I've been able to reproduce your defect and yes, it was an issue similar to, but not identical with, the other issues you indicated.

I have fixed all these issues and they will be available in the next maintenance release which will be published at the beginning of September.

Your project runs correctly here, with the corrected source, using either threads or not.

Posted: Wed Aug 02, 2006 12:16 pm
by 9639856
Hi Christopher,

Thanks for your reply.
It's good to know that you already had fixed these issues.
There is a way to you to release a version with this corrections? I'm asking this because we have a deadline to release our application in august and these issues are the only thing that remains.

Thanks.

Posted: Wed Aug 02, 2006 2:48 pm
by Chris
Hello,

August is a very complicated month here, as the great majority of Steema staff are already on holiday or are just about to start their holidays.

There is a chance that we might be able to get a maintenance release out within the next 7 to 8 working days but I'm afraid I can't commit to that.

Posted: Wed Aug 02, 2006 3:02 pm
by 9639856
Ok then, for now we'll try to swicth to the activeX version until you releases he version for .NET with the corrections.
One more question the new version for .NET will be a new release for the 2.0 version or a new version (like 3.0), I'm asking because I need to know if we'll need to upgrade our license.

Thanks again.

Posted: Wed Aug 02, 2006 3:15 pm
by Chris
Hello,

No, it will not require a license upgrade as will be a maintenance release of version 2.0.

We are concurrently working on version 3.0 which we hope to have ready by the middle of the fourth quarter of this year.

Posted: Wed Aug 02, 2006 7:09 pm
by 9639856
Ok.
So we'll wait for the next version. Until there we'll try to use the activeX version.

Thanks again.