加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – BackgroundWorker OnWorkCompleted抛出跨线程异常

发布时间:2020-12-15 23:52:06 所属栏目:百科 来源:网络整理
导读:我有一个简单的UserControl用于数据库分页,它使用控制器来执行实际的DAL调用.我使用BackgroundWorker来执行繁重的工作,并在OnWorkCompleted事件上重新启用一些按钮,更改TextBox.Text属性并为父窗体引发事件. 表单A保存我的UserControl.当我点击打开表单B的某
我有一个简单的UserControl用于数据库分页,它使用控制器来执行实际的DAL调用.我使用BackgroundWorker来执行繁重的工作,并在OnWorkCompleted事件上重新启用一些按钮,更改TextBox.Text属性并为父窗体引发事件.

表单A保存我的UserControl.当我点击打开表单B的某个按钮时,即使我没有做任何“那里”并且只是关闭它,并尝试从我的数据库引入下一页,OnWorkCompleted会在工作线程上被调用(而不是我的主线程),并抛出一个跨线程异常.

目前我在那里的处理程序中添加了对InvokeRequired的检查,但是不是要在主线程上调用OnWorkCompleted的全部内容吗?为什么不按预期工作?

编辑:

我设法将问题缩小到arcgis和BackgroundWorker.我有以下解决方案,它向arcmap添加一个命令,打开一个带有两个按钮的简单Form1.

第一个按钮运行一个休眠500毫秒的BackgroundWorker并更新计数器.
在RunWorkerCompleted方法中,它检查InvokeRequired,并更新标题以显示方法最初在主线程或工作线程内运行.
第二个按钮只打开Form2,它什么都没有.

首先,所有对RunWorkerCompletedare的调用都是在主线程内完成的(正如预期的那样 – 这就是RunWorkerComplete方法的最后一点,至少我从BackgroundWorker上的MSDN中了解到这一点)

打开和关闭Form2后,始终在工作线程上调用RunWorkerCompleted.我想补充一点,我可以将此解决方案保留原样(在RunWorkerCompleted方法中检查InvokeRequired),但我想了解为什么它会违背我的期望.在我的“真实”代码中,我想知道在主线程上调用RunWorkerCompleted方法.

我设法在form.Show();我的BackgroundTesterBtn中的命令 – 如果我使用ShowDialog(),我没有问题(RunWorkerCompleted总是在主线程上运行).我需要在我的ArcMap项目中使用Show(),这样用户就不会绑定到表单了.

我还尝试在正常的WinForms项目上重现该错误.我添加了一个简单的项目,只打开没有ArcMap的第一个表单,但在这种情况下我无法重现该错误 – RunWorkerCompleted在主线程上运行,无论我在打开Form2之前和之后使用Show()还是ShowDialog() .我尝试在Form1之前添加第三个表单作为主表单,但它没有改变结果.

Here是我的简单sln(VS2005sp1) – 它需要

ESRI.ArcGIS.ADF(9.2.4.1420)

ESRI.ArcGIS.ArcMapUI(9.2.3.1380)

ESRI.ArcGIS.SystemUI(9.2.3.1380)

解决方法

它看起来像一个bug:

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

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

所以我建议使用防弹(伪代码):

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读