跨线程操作无效,即使使用InvokeRequired [英] Cross-thread operation not valid, even if using InvokeRequired

查看:170
本文介绍了跨线程操作无效,即使使用InvokeRequired的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格,上面有我的自定义控件。

I have a form with my custom controls on it.

我有一个方法,在我的表格:

I have a method in my Form:

private void SetEnabledOnControls(bool val)
{
  if (InvokeRequired)
  {
      Invoke((Action<bool>)SetEnabledOnControls, val);
  }
  else
  {
       //do the work - iterate over child controls, 
       //and they iterate over their children, etc...
  }
}

和内部是在其他分支我得到的提到的异常的方法:
跨线程操作无效:控制'txtNumber'从一个线程比它创建于其他线程访问

And inside the methods that are on the else branch I get the mentioned exception:
Cross-thread operation not valid: Control 'txtNumber' accessed from a thread other than the thread it was created on.

我的方案实际上是一个比较复杂一点 - 我只是推断这是一个例子。什么实际发生的是,我使用WorkflowFoundation - 我有StateMachineActivity(CTP1)在WorkflowApplication(运行在它自己的线程)上运行,我订阅了它的活动,并从那里我打电话 SetEnabledOnControls 。此外,我使用书签恢复我的工作流(也,有在旁边MEF,没有参与的情况下)。

My scenario is actually a bit more complicated - I just extrapolated this as an example. What's actually going on is that I'm using WorkflowFoundation - I have StateMachineActivity (CTP1) running in WorkflowApplication (which runs in it's own thread), I subscribed to it's event, and from there I'm calling SetEnabledOnControls. Also, I'm using bookmarks to resume my workflow (and also, there's MEF on the side, not involved in the scenario).

所有这些是无关的InvokeRequired我明显的误区 - 怎么可能,如果InvokeRequired是假的,我已经跨线程异常?我不创造任何控件的'手工' - 这一切都没有在初始化()放置由设计师。

All of that is irrelevant to my obvious misunderstanding of the InvokeRequired - how is it possible that if the InvokeRequired is false, I have cross threaded exception? I don't create any of the controls 'manually' - it's all there in the Initialize() placed by designer.

任何人都可以揭示出这个一些轻?

Can anyone shed some light on this?

谢谢!

修改 使用GWLlosa的建议,我试着使用 System.Threading.Thread.CurrentThread.ManagedThreadId 跟踪的ThreadId。现在到了怪异的一部分......在初始化线程ID()是10。通过第一个2状态之间,它与编号13 - InvokeRequired是真实的,它调用正确。但第二状态后,当它进入 SetEnabledOnControls 这是一次13,但这次InvokeRequired是假的!怎么来的!?稍后,当然,它不能改变子控件(并不奇怪)。难道说表单某种程度上改变了它的生活在??线程

EDIT Using GWLlosa suggestion, I've tracked the ThreadId using System.Threading.Thread.CurrentThread.ManagedThreadId. Now comes the weird part... the thread id in Initialize() is 10. Between passing the first 2 states, it comes in with Id 13 - InvokeRequired was true, and it invoked correctly. BUT, after the second state, when it enters SetEnabledOnControls it's again 13, but this time InvokeRequired is false! How come!? Later on, of course, it fails to change child controls (not surprising). Could it be that the Form somehow changed the thread it's living in??

编辑2 现在,我打电话有:

EDIT 2 Now I'm calling with:

 if (IsHandleCreated)
 {
     Invoke((Action<bool>)SetEnabledOnControls, val);
 }

和它 IsHandleCreated 为真,但仍无法与什么devSpeed​​ <一个href="http://stackoverflow.com/questions/808867/invoke-or-begininvoke-cannot-be-called-on-a-control-until-the-window-handle-has-b">pointed在。

and it has IsHandleCreated to true, but still fails with what devSpeed pointed at.

修改3 FACEPALM 的:)一说是恢复状态的按钮起初CancelButton的形式。当它被从财产等拆除,codebihind仍存在的DialogResult =取消它 - 所以我的形式确实关闭了,当然这是缺少手柄使InvokeRequired没有返回正确的信息,并因此错误。

EDIT 3 FACEPALM :) One of the buttons that were resuming state was at first CancelButton for the Form. When it was removed from the property as such, the codebihind still had the DialogResult=Cancel for it - so my form was indeed closing, and of course it was missing the handle so the InvokeRequired didn't return correct info, and hence the errors.

谢谢大家!我今天学到了新的东西:)

Thanks everyone! I learned a new thing today :)

推荐答案

也许你正在运行到<一个href="http://stackoverflow.com/questions/808867/invoke-or-begininvoke-cannot-be-called-on-a-control-until-the-window-handle-has-b">this问题的。

Maybe you are running into this problem.

这篇关于跨线程操作无效,即使使用InvokeRequired的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆