第一个话题是What wrong with my InvokeRequied
我按照他向我推荐的答案进行了操作,但我发现了一个新问题。
下图的结果是跨线程异常。
我的代码有什么问题?
如何解决这个问题呢 ?
最佳答案
根据 MSDN InvokeRequired
可以返回 false
即使在 InvokeRequired
应该是 true
的情况下 - 即在您访问 InvokeRequired
之前该控件/表单(或其父)的 Handle
已创建的情况下。
基本上你的支票是不完整的,这导致你看到的结果。
您需要检查 IsHandleCreated
- 如果那是 false
,那么无论 Invoke
返回什么,您都需要使用 BeginInvoke
/InvokeRequired
。
[更新]
但是 :
这通常不会有效地工作,因为 Invoke
/BeginInvoke
检查哪个线程创建了 Handle
来做他们的魔术......
[/更新]
仅当 IsHandleCreated
是 true
时,您才根据 InvokeRequired
返回的内容采取行动 - 类似以下内容:
if (control.IsHandleCreated)
{
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action.Invoke();
}
}
else
{
// in this case InvokeRequired might lie - you need to make sure that this never happens!
throw new Exception ( "Somehow Handle has not yet been created on the UI thread!" );
}
[更新]
因此,以下对于避免此问题很重要
始终确保在第一次访问 UI 线程以外的线程之前已经创建了
Handle
。根据 MSDN,您只需要在 UI 线程中引用
control.Handle
即可强制创建它 - 在您的代码中,这必须在您第一次从非 UI 线程的任何线程访问该控件/表单之前发生。[/更新]
关于c# - 我的 InvokeRequired #2 有什么问题?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8946590/