BackgroundWorker的OnWorkCompleted抛出跨线程异常 [英] BackgroundWorker OnWorkCompleted throws cross-thread exception
问题描述
我对数据库分页,使用一个控制器来执行实际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 $ C $整点时刻C>是在主线程上被称为?如预期为什么不工作?
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屋!