我有一个简单的UserControl用于数据库分页,它使用控制器来执行实际的DAL调用.我使用a BackgroundWorker来执行繁重的工作,并在OnWorkCompleted事件中重新启用一些按钮,更改TextBox.Text属性并为父表单引发事件.
表单A保存我的UserControl.当我点击打开表单B的某个按钮时,即使我没有做任何"那里"并且只是关闭它,并尝试从我的数据库中引入下一页,OnWorkCompleted在工作线程上调用它(而不是我的主线程),并抛出一个跨线程异常.
目前我InvokeRequired在那里的处理程序中添加了一个检查,但是不是OnWorkCompleted要在主线程上调用的全部内容?为什么不按预期工作?
编辑:
我已经设法将问题缩小到arcgis和BackgroundWorker.我有以下解决方案,它添加了一个命令到arcmap,打开一个简单Form1的两个按钮.
第一个按钮运行BackgroundWorker睡眠500毫秒并更新计数器.在该RunWorkerCompleted方法中,它检查InvokeRequired并更新标题,以显示该方法最初在主线程或工作线程内运行.第二个按钮刚打开Form2,不包含任何内容.
首先,所有调用RunWorkerCompletedare都在主线程内完成(正如预期的那样 - 这就是RunWorkerComplete方法的最后一点,至少我从MSDN上了解到的BackgroundWorker)
打开和关闭后Form2,RunWorkerCompleted始终在工作线程上调用.我想补充一点,我可以将此解决方案保留原样(InvokeRequired在RunWorkerCompleted方法中检查),但我想了解为什么它会违背我的期望.在我的"真实"代码中,我想知道该RunWorkerCompleted方法是在主线程上调用的.
我设法form.Show();在我的命令中指出问题BackgroundTesterBtn- 如果我使用ShowDialog(),我没有问题(RunWorkerCompleted总是在主线程上运行).我需要Show()在我的ArcMap项目中使用,以便用户不会绑定到表单.
我还尝试在正常的WinForms项目上重现该错误.我添加了一个简单的项目,只打开没有ArcMap的第一个表单,但在这种情况下我无法重现错误 - RunWorkerCompleted主线程上的运行,无论是我使用的Show()还是ShowDialog()在打开之前和之后Form2.我尝试在我之前添加第三个表单作为主要表单Form1,但它没有改变结果.
这是我的简单sln(VS2005sp1) - 它需要
ESRI.ArcGIS.ADF(9.2.4.1420)
ESRI.ArcGIS.ArcMapUI(9.2.3.1380) …