BackgroundWorker的OnWorkCompleted抛出跨线程异常 [英] BackgroundWorker OnWorkCompleted throws cross-thread exception

查看:237
本文介绍了BackgroundWorker的OnWorkCompleted抛出跨线程异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对数据库分页,使用一个控制器来执行实际DAL调用一个简单的用户控件。我用的是的BackgroundWorker 来执行繁重,并在 OnWorkCompleted 事件中,我重新启用一些按钮,更改 TextBox.Text 财产和提高对父窗体的事件。

I have a simple UserControl for database paging, that uses a controller to perform the actual DAL calls. I use a BackgroundWorker to perform the heavy lifting, and on the OnWorkCompleted event I re-enable some buttons, change a TextBox.Text property and raise an event for the parent form.

A型持有我的用户。当我点击一些按钮,打开表B,即使我没有做任何事情,那里,只是将其关闭,并尝试在接下来的页面,使从我的数据库中, OnWorkCompleted 被调用的工作线程上(而不是我的主线程),并抛出一个跨线程异常。

Form A holds my UserControl. When I click on some button that opens form B, even if I don't do anything "there" and just close it, and try to bring in the next page from my database, the OnWorkCompleted gets called on the worker thread (and not my Main thread), and throws a cross-thread exception.

在我添加的处理程序有没有 InvokeRequired 的支票,而不是 OnWorkCompleted 是在主线程上被称为?如预期为什么不工作?

At the moment I added a check for InvokeRequired at the handler there, but isn't the whole point of OnWorkCompleted is to be called on the Main thread? Why wouldn't it work as expected?

编辑:

我设法缩小问题到ArcGIS和的BackgroundWorker 。我有以下解决方案至极增加了一个命令到ArcMap,打开一个简单的 Form1中有两个按钮。

I have managed to narrow down the problem to arcgis and BackgroundWorker. I have the following solution wich adds a Command to arcmap, that opens a simple Form1 with two buttons.

第一个按钮运行的BackgroundWorker 的休眠500毫秒和更新的计数器。
RunWorkerCompleted 方法,它检查 InvokeRequired ,并更新标题显示whethever该法的渊源的主要内部运行线程或辅助线程。
第二个按钮只是打开窗体2 ,其中包含了什么。

The first button runs a BackgroundWorker that sleeps for 500ms and updates a counter. In the RunWorkerCompleted method it checks for InvokeRequired, and updates the title to show whethever the method was originaly running inside the main thread or the worker thread. The second button just opens Form2, which contains nothing.

首先,所有的来电 RunWorkerCompletedare 的主线程中所做的(正如预期的那样 - 至少是我从了解多数民众赞成在RunWorkerComplete方法的whold点 MSDN上 的BackgroundWorker

At first, all the calls to RunWorkerCompletedare are made inside the main thread (As expected - thats the whold point of the RunWorkerComplete method, At least by what I understand from the MSDN on BackgroundWorker)

打开和关闭后窗体2 RunWorkerCompleted 总是被称为工作线程。我想补充一点,我可以离开这个问题的解决方法为是(检查 InvokeRequired RunWorkerCompleted 方法),但我想知道为什么它正在发生对我的期望。在我的真正的code,我想总是知道 RunWorkerCompleted 方法被调用在主线程。

After opening and closing Form2, the RunWorkerCompleted is always being called on the worker thread. I want to add that I can just leave this solution to the problem as is (check for InvokeRequired in the RunWorkerCompleted method), but I want to understand why it is happening against my expectations. In my "real" code I'd like to always know that the RunWorkerCompleted method is being called on the main thread.

我设法针点在 form.Show()问题;在命令我的 BackgroundTesterBtn - 如果我使用的ShowDialog()而不是,我没有得到任何问题( RunWorkerCompleted 始终运行在主线程)。我确实需要使用显示()在我的ArcMap中的项目,这样用户将不会绑定到窗体。

I managed to pin point the problem at the form.Show(); command in my BackgroundTesterBtn - if I use ShowDialog() instead, I get no problem (RunWorkerCompleted always runs on the main thread). I do need to use Show() in my ArcMap project, so that the user will not be bound to the form.

我也试图重现正常的WinForms项目的bug。我添加了一个简单的项目,只是没有打开ArcMap中的第一种形式,但在这种情况下,我无法重现的错误 - 在主线程中的 RunWorkerCompleted 跑了,不管我用显示()的ShowDialog(),前后开盘后窗体2 。我尝试添加第三种形式,作为我的 Form1中,但它并没有改变结果之前,主要形式。

I also tried to reproduce the bug on a normal WinForms project. I added a simple project that just opens the first form without ArcMap, but in that case I couldn't reproduce the bug - the RunWorkerCompleted ran on the main thread, whether I used Show() or ShowDialog(), before and after opening Form2. I tried adding a third form to act as a main form before my Form1, but it didn't change the outcome.

这里是我的简单SLN(VS2005sp1) - 它需要

Here is my simple sln (VS2005sp1) - it requires

ESRI.ArcGIS.ADF(9.2.4.1420)

ESRI.ArcGIS.ADF(9.2.4.1420)

ESRI.ArcGIS.ArcMapUI(9.2.3.1380)

ESRI.ArcGIS.ArcMapUI(9.2.3.1380)

ESRI.ArcGIS.SystemUI(9.2.3.1380)

ESRI.ArcGIS.SystemUI (9.2.3.1380)

推荐答案

它看起来像一个错误:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=116930

http://thedatafarm.com/devlifeblog/archive/2005/ 12月21日/ 39532.aspx

因此​​,我建议使用防弹(伪code):

So I suggest using the bullet-proof (pseudocode):

if(control.InvokeRequired)
  control.Invoke(Action);
else
  Action()

这篇关于BackgroundWorker的OnWorkCompleted抛出跨线程异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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