我正在尝试从另一个线程更改控件上的 Text 属性。我正在使用这种方法来做到这一点:
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired)
{
try
{
control.Invoke(action);
}
catch (ObjectDisposedException) { }
catch (InvalidAsynchronousStateException) { }
}
else
{
action();
}
}
'System.InvalidOperationException'
使用此方法时,我仍然遇到异常。当我闯入这个时,我可以看到它control.InvokeRequired
,false
但看起来它实际上是从另一个线程访问的??
在实际的错误消息中,它并没有给我我试图调用的控件。相反,它给了我控件所在的形式,说明'Form1 accessed from a thread other than the thread it was created on'.
我尝试将表单传递给InvokeIfRequired
方法,但仍然Form1.InvokeRequired
存在false
并且发生异常。我试图调用的控件是在设计器中创建的。
这是我用来编辑控件的代码:
private void StartUpdateThreads() // called from the Form ctor
{
new Thread(new ThreadStart(this.TimeUpdater)).Start();
new Thread(new ThreadStart(this.AccountBalanceUpdater)).Start();
}
private void TimeUpdater()
{
while (!this.IsDisposed)
{
Utilities.InvokeIfRequired(this, (MethodInvoker)(() =>
{
this.timestampLabel.Text = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
}));
Thread.Sleep(250);
}
}
这是调用堆栈:
MyApp.exe!MyApp.MyAppToolbar.TimeUpdater.AnonymousMethod__0() Line 133 + 0x41 bytes
MyApp.exe!MyApp.Utilities.InvokeIfRequired(System.Windows.Forms.Control control, System.Windows.Forms.MethodInvoker action) Line 34 + 0xb bytes
MyApp.exe!MyApp.MyAppToolbar.TimeUpdater() Line 131 + 0x49 bytes
这是堆栈跟踪:
at System.Windows.Forms.Control.get_Handle()\r\n
at System.Windows.Forms.Control.get_InternalHandle()\r\n
at System.Windows.Forms.Control.get_CreateParams()\r\n
at System.Windows.Forms.Label.get_CreateParams()\r\n
at System.Windows.Forms.Control.SizeFromClientSize(Int32 width, Int32 height)\r\n
at System.Windows.Forms.Control.SizeFromClientSize(Size clientSize)\r\n
at System.Windows.Forms.Label.GetBordersAndPadding()\r\n
at System.Windows.Forms.Label.GetPreferredSizeCore(Size proposedConstraints)\r\n
at System.Windows.Forms.Control.GetPreferredSize(Size proposedSize)\r\n
at System.Windows.Forms.Label.GetPreferredSize(Size proposedSize)\r\n
at System.Windows.Forms.Control.get_PreferredSize()\r\n
at System.Windows.Forms.Label.AdjustSize()\r\n
at System.Windows.Forms.Label.OnTextChanged(EventArgs e)\r\n
at System.Windows.Forms.Control.set_Text(String value)\r\n
at System.Windows.Forms.Label.set_Text(String value)\r\n
at MyApp.MyAppToolbar.<TimeUpdater>b__0() in PATH\\TO\\FILE.cs:line 133\r\n
at MyApp.Utilities.InvokeIfRequired(Control control, MethodInvoker action) in PATH\\TO\\FILE.cs:line 34\r\n MyApp.MyAppToolbar.TimeUpdater() in PATH\\TO\\FILE.cs:line 131\r\n
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)\r\n
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
at System.Threading.ThreadHelper.ThreadStart()
有人可以在这里指出我正确的方向吗?