在编辑显然不需要调用的控件时异常
本文关键字:控件 异常 调用 不需要 编辑 | 更新日期: 2023-09-27 18:17:35
我试图从另一个线程更改控件的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()
谁能给我指一下正确的方向?
阅读InvokeRequired
的文档,您可以看到当控件的句柄尚未创建时,它返回false
。
IsHandleCreated
的值。还有一个关于销毁时间的问题,正如Hans上面所说的,所以当在正确的线程中时,您可能想要检查控件是否已经被处置。
另一种方法是在控件完全加载时启动后台线程,但这再次使InvokeIfRequired
不是一个通用工具。
夏洛克,我想这会对你有帮助http://msdn.microsoft.com/en-us/library/ms171728 (v = vs.80) . aspx