我有一个winforms应用程序,问题与线程有关.因为我调用'MyCustomCode()来创建一个新线程,并调用方法'SomeMethod()'然后访问MessageBox.Show(...).
问题与线程有关,因为新创建的线程正在尝试访问在另一个线程上创建的控件.
我收到错误:
跨线程操作无效:控制'TestForm'从其创建的线程以外的线程访问.
public TestForm() { InitializeComponent(); // custom code // MyCustomCode(); } public void SomeMethod() { // ***** This causes an error **** MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } private void InitializeAutoUpdater() { // Seperate thread is spun to keep polling for updates ThreadStart ts = new ThreadStart(SomeMethod); pollThread = new Thread(ts); pollThread.Start(); }
更新
如果你看一下这个例子http://www.codeproject.com/KB/cs/vanillaupdaterblock.aspx,CheckAndUpdate方法正在调用MessageBox.Show(..),这就是我的问题所在.我本以为代码很好用!
有趣的是,这个代码在星期五工作得很好???
您无法从多个线程访问UI元素.
解决此问题的一种方法是使用UI元素(如消息框)调用具有委托的控件的Invoke方法.有些喜欢:
public delegate void InvokeDelegate(); public void SomeMethod() { button1.Invoke((InvokeDelegate)doUIStuff); } void doUIStuff() { MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); }
为了避免跨线程异常(InvalidOperationException),这里是代码模式:
protected delegate void someGuiFunctionDelegate(int iParam); protected void someGuiFunction(int iParam) { if (this.InvokeRequired) { someGuiFunctionDelegate dlg = new someGuiFunctionDelegate(this.someGuiFunction); this.Invoke(dlg, new object[] { iParam }); return; } //do something with the GUI control here }
我同意这很烦人,但它是Windows GUI控件不是线程安全的事实.可以通过某处或其他地方的标志关闭该异常,但不要这样做,因为它可能导致极难找到错误.