Note that there are some explanatory texts on larger screens.

plurals
  1. POLinkedList modified, Thread crashing the program
    primarykey
    data
    text
    <p>My problem is a synchronization problem with a thread and the user simultaneously accessing and modifying a <code>LinkedList</code>.</p> <p>I’m making a program in C# that will display some messages in a panel. I’m getting an error called “The collection was modified after the enumerator was instantiated.”, that is because I’m adding or removing messages while a thread is accessing the <code>LinkedList</code>.</p> <p>I have read some solutions but I am still unable to make them work. I’m using an <code>Enumerator</code> for the thread work in my <code>LinkedList</code>. I tried to make some locks in my code so the thread would not iterate the list while I remove or add an element. I also tried to lock the thread for the operations on my list. But all my attempts failed.</p> <p>Here is some code of my project. This one is for <strong>adding a message</strong>:</p> <pre><code>public void addMsg(MsgForDisplay msg) { Label lbl = new Label(); lbl.Text = (msg.getMsgText() + " -"); lbl.ForeColor = color; lbl.Font = textFont; lbl.BackColor = backg; lbl.Visible = true; lbl.AutoSize = true; lbl.Location = new Point(width(), 0); //lock(labels) { tried to lock here but failed labels.AddLast(lbl); lastLb = lbl; this.Controls.Add(lbl); this.Refresh(); //} } </code></pre> <p><strong>Removing a message</strong>:</p> <pre><code>public void removeMsg(string msg) { string remove = msg + " -"; Label lbRemove = null; //lock(labels) { also tried to lock here var it = labels.GetEnumerator(); while(it.MoveNext()) { Label label = it.Current; if (label.Text.Equals(remove)) { lbRemove = label; } } labels.Remove(lbRemove); this.Controls.Remove(lbRemove); this.Refresh(); //} } </code></pre> <p>And there is the problem, in <strong>my thread</strong>:</p> <pre><code>public void run() { while (true) { // lock (labels) { also tried to lock here var it = labels.GetEnumerator(); while (it.MoveNext()) { // the crash occurs here Label lb = it.Current; if (lb.Location.X + lb.Width &lt; 0) { this.Invoke(new MethodInvoker(() =&gt; { this.Controls.Remove(lb); })); if (labels.Count &gt; 1) this.Invoke(new MethodInvoker(() =&gt; { lb.Location = new Point(lastLb.Right, 0); })); else this.Invoke(new MethodInvoker(() =&gt; { lb.Location = new Point(2000, 0); })); lastLb = lb; this.Invoke(new MethodInvoker(() =&gt; { this.Controls.Add(lb); })); this.Invoke(new MethodInvoker(() =&gt; { this.Refresh(); })); } if (leftLb != null) if (leftLb.Location.X + leftLb.Width - lb.Location.X &lt; -20) this.Invoke(new MethodInvoker(() =&gt; { lb.Location = new Point(leftLb.Right, 0); })); else this.Invoke(new MethodInvoker(() =&gt; { lb.Location = new Point(lb.Location.X - 3, lb.Location.Y); })); leftLb = lb; } System.Threading.Thread.Sleep(30); // } } } </code></pre> <p>As you can see I’m using an <code>GetEnumerator</code> of my labels, what in Java should be the <code>Iterator</code>. With this I shouldn’t be able to iterate the list without problem when the user add or remove messages?</p> <p>Is there a way to synchronize the accesses to the list?</p> <p><strong>EDIT</strong>: I have tried the <code>ConcurrentBag</code> and <code>ConcurrentDictionary</code> but without any improvement to the project as you can see in the comments…</p> <p>Please before you post an answer read the comments bellow to make sure that you know what is going on.</p> <p><strong>EDIT</strong>: Tried to add a mutex to my code for <code>addMsg</code> and <code>removeMsg</code> but still crashing. If I use the mutex in the thread it will be slowed down.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload