The following code is used to generate the value on the label.
///Метод является членом класса LabelReg, LabelReg отнаследован от Label protected void reg_OnResultRead(Reg sender, ModBusCommon.Error result, object data) { ///Получили новые данные double value = Convert.ToDouble(data) * Factor; ///Формируется текст для вывода StringBuilder sb = new StringBuilder(); ///Если заданы размерности параметра, формируем текст по формату if (Units.Length > 0) { sb.Append(DisplayFormat.Replace("<VALUE>", value.ToString(Format))); sb.Replace("<UNITS>", Units); } else sb.Append(value.ToString(Format)); Action d = () => { ///Собственно здесь происходит исключение this.Text = sb.ToString(); this.Enabled = (result == ModBusCommon.Error.OK); }; if (this.InvokeRequired) this.Invoke(d); else d(); }
Periodically, when assigning to the Text property, a System.InvalidOperationException is thrown.
The collection was changed after creating an instance of the enumerator.
in System.Collections.Specialized.ListDictionary.NodeEnumerator.MoveNext ()
in System.Windows.Forms.Layout.DefaultLayout.ApplyCachedBounds (IArrangedElement container)
in System.Windows.Forms.Layout.DefaultLayout.xLayout (IArrangedElement container, Boolean measureOnly, Size & preferredSize)
in System.Windows.Forms.Layout.DefaultLayout.LayoutCore (IArrangedElement container, LayoutEventArgs args)
in System.Windows.Forms.Layout.LayoutEngine.Layout (Object container, LayoutEventArgs layoutEventArgs)
in System.Windows.Forms.Control.OnLayout (LayoutEventArgs levent)
in System.Windows.Forms.ScrollableControl.OnLayout (LayoutEventArgs levent)
in System.Windows.Forms.Control.PerformLayout (LayoutEventArgs args)
in System.Windows.Forms.Control.PerformLayout ()
in System.Windows.Forms.Control.ResumeLayout (Boolean performLayout)
in System.Windows.Forms.Layout.LayoutTransaction.Dispose ()
in System.Windows.Forms.Label.OnTextChanged (EventArgs e)
in System.Windows.Forms.Control.set_Text (String value)
in System.Windows.Forms.Label.set_Text (String value)
in WFControlsLib2.ModBusControls.LabelReg. <> c__DisplayClass1.b__0 (Object s, EventArgs e)
In D: \ doc \ C # \ WFControlsLib2 \ ModBusControls \ LabelReg.cs: line 304
in WFControlsLib2.ModBusControls.LabelReg.reg_OnResultRead (Reg sender, Error result, Object data)
in D: \ doc \ C # \ WFControlsLib2 \ ModBusControls \ LabelReg.cs: line 311
in System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage (IntPtr md, Object [] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object [] & outArgs)
in System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage (iMessage msg, iMessageSink replySink)
How to fix this problem? In theory, I simply set the text value of the Text property to the Label class.
Update ... Overloaded and locked Text method
public override string Text { get { lock (mutex) { return base.Text; } } set { lock (mutex) { base.Text = value; } } }
object type mutex, a member of the class, the problem remains.
Units
? Preferred sample code. - Stepan KasyanenkoStringBuilder
, but using just aString
. Or, as advised below, create a variablevar tmp = sb.ToString();
before creatingAction d = ...
And inside the anonymous function, usetmp
and notsb
. - Stepan KasyanenkoLayot
processing (PerformLayout
,ResumeLayout
, etc.). That is, when adding / changing text in alabel
, the control element is rewritten. Since the error clearly indicates that the Collection was changed after creating an instance of the enumerator , it is possible that somewhere in another thread the controllers in this container are changed (added / deleted). - Stepan Kasyanenko