第一个主题是我的 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!" );
}
[更新]
因此,以下对于避免此问题很重要
始终确保Handle
在第一次访问 UI 线程以外的线程之前已经创建了 。
根据MSDN,您只需要control.Handle
在 UI 线程中引用以强制创建它 - 在您的代码中,这必须在您第一次从任何不是 UI 线程的线程访问该控件/表单之前发生。
[/更新]