我抛出以下异常:
在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke.
这是我的代码:
if (InvokeRequired)
{
BeginInvoke(new UpdateTextFieldDelegate(WriteToForm), finished, numCount);
}
else
Invoke(new UpdateTextFieldDelegate(WriteToForm), finished, numCount);
Run Code Online (Sandbox Code Playgroud)
我在这个网站上找到了关于这个主题的网页,但我不知道出了什么问题.
Rob*_*ker 54
Invoke和BeginInvoke之间的区别在于前者是同步的(等待完成),而后者是异步的(类似于"忘掉").但是,两者都通过向UI消息循环发布消息来工作,这将导致委托在到达该消息时执行.
InvokeRequired属性确定您是否需要完全调用或者是否已经在正确的线程上,而不是您是否需要同步或异步调用.如果InvokeRequired为false,您(理论上)已经在UI线程上运行,并且可以直接执行同步操作(或者如果需要异步触发它们,则仍然是BeginInvoke).这也意味着如果InvokeRequired为false,则无法使用Invoke,因为当前线程上的消息循环无法继续.这是您上面的代码的一个大问题,但不一定是您报告的错误.在任何一种情况下,如果你注意递归调用,你实际上可以使用BeginInvoke,依此类推.
但是,如果没有窗口句柄,则不能使用任何一个.如果表单/控件已经实例化但未初始化(即,在它首次显示之前),它可能还没有句柄.并且Dispose()会清除句柄,例如在Form关闭后.在任何一种情况下,InvokeRequired都将返回false,因为没有句柄就无法调用.您可以检查IsDisposed,并且还有一个属性IsHandleCreated,它更具体地测试句柄是否存在.通常,如果IsDisposed为真(或者如果IsHandleCreated为false),您想要进入一个特殊情况,例如简单地将操作丢弃为不适用.
所以,你想要的代码可能更像是:
if (IsHandleCreated)
{
// Always asynchronous, even on the UI thread already. (Don't let it loop back here!)
BeginInvoke(new UpdateTextFieldDelegate(WriteToForm), finished, numCount);
return; // Fired-off asynchronously; let the current thread continue.
// WriteToForm will be called on the UI thread at some point in the near future.
}
else
{
// Handle the error case, or do nothing.
}
Run Code Online (Sandbox Code Playgroud)
或者可能:
if (IsHandleCreated)
{
// Always synchronous. (But you must watch out for cross-threading deadlocks!)
if (InvokeRequired)
Invoke(new UpdateTextFieldDelegate(WriteToForm), finished, numCount);
else
WriteToForm(finished, numCount); // Call the method (or delegate) directly.
// Execution continues from here only once WriteToForm has completed and returned.
}
else
{
// Handle the error case, or do nothing.
}
Run Code Online (Sandbox Code Playgroud)
这通常发生在多线程场景中,其中一些外部源(可能是NetworkStream)在表单正确初始化之前将数据推送到表单.
在处理表单后,也可以显示该消息.
您可以检查IsHandleCreated是否已创建表单,但是您需要将所有内容放入正确的错误处理中,因为Invoke如果您在应用程序关闭时尝试更新表单,则语句可能会引发异常.
在调用调用方法之前添加以下内容:
while (!this.IsHandleCreated)
System.Threading.Thread.Sleep(100)
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我有用。
这是我的答案
假设你想在文本框中写"Hello World".然后,如果您使用"Ishandlecreated",那么如果尚未创建处理程序,则不会执行您的操作.因此,如果尚未创建,则必须强制自己使用CreateHandlers.
这是我的代码
if (!IsHandleCreated)
this.CreateControl();
this.Invoke((MethodInvoker)delegate
{
cmbEmail.Text = null;
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
43911 次 |
| 最近记录: |