是BackgroundWorker.RunWorkerCompleted线程安全

时间:2013-09-14 19:34:25

标签: .net wpf backgroundworker

有一个很难再现的问题 例外是:

e.Exception.Message = Object reference not set to an instance of an object.
e.Exception.StackTrace 
at System.Windows.Controls.ItemContainerGenerator.MoveToPosition(GeneratorPosition position, GeneratorDirection direction, Boolean allowStartAtRealizedItem, GeneratorState& state)
at System.Windows.Controls.ItemContainerGenerator.Generator..ctor(ItemContainerGenerator factory, GeneratorPosition position, GeneratorDirection direction, Boolean allowStartAtRealizedItem)

我在App.cs App_DispatcherUnhandledException

中捕获了它

我认为这是来自XAML,因为我在Visual Studio中为每个选项打开了Break on Thrown 而且我很确定我将所有代码包含在Try Catch中 确保我认为错误源自的页面正在捕获异常背后的所有代码 如果我打破那些公共财产的获取,我无法重现错误 当我放慢速度以尝试调试时,它很难再现。

有一些标签,我使用TextBlock显示文本,使用FlowDocumentViewer格式化文本。

来源与公共财产绑定。 TextBlock.Text的公共属性是RawText,后备变量是rawText。

我获取文本和信息来格式化在UI线程上创建的BackgroundWorker上的文本。
在调用BackgroundWorker之前,我将rawText设置为“获取文本”,如果BackgroundWorker是IsBusy则调用CancelAsync()。 然后在RunWorkerCompletedEventHandler上,我将rawText设置为实际文本。 然后我只调用notifypropertychanged如果选中该选项卡,那么如果它不可见则不会渲染。

问题是我在控件读取rawText时是否正在更改RunWorkerCompletedEventHandler中的rawText?或者我在UI控件读取文本时将rawText更改为“获取文本”?

还有其他想法吗?

将锁定放在这些作业上会修复它吗?

不是MVVM。

我认为我已充分描述了代码,但显然没有。

rawText = "getting text";
backgroundWorker.RunWorkerAsync(input);

然后在RunWorkerCompleted

DocTextAndHighlight docTextAndHighlight = (GabeLib.DocTextAndHighlight)e.Result;
rawText = docTextAndHighlight.RawText;

只有在该选项卡打开时才会调用RawText上的NotifyPropertyChanged。

添加了锁定并且无法重现错误,但这并不意味着它已经消失 将不得不在生产中进行测试 还添加了pass to through转换为我怀疑的控件并写出调试消息 什么不是抛出异常,异常告诉我什么。

这可能是一个带有DDE接口的旧com组件 一个方法调用报告这个完全相同的错误 这是一个方法调用,只能在10,000中失败1 但是如果它失败了它就会失败 并且该调用是在try catch块中,但由于某种原因它不会被直接阻塞。 当然,错误的信息很少,但它是完全相同的错误。 不好的一面是它崩溃了应用程序 我可以设置e.Handled = true;但它仍然会错误地引发错误以使应用程序崩溃。

1 个答案:

答案 0 :(得分:2)

DoWork将在线程池线程上运行,RunWorkerCompleted将在UI线程上运行,提供您的BackgroundWorker是在UI线程上创建的。

来自MSDN:

  

在访问RunWorkerCompletedEventArgs.Result属性之前,RunWorkerCompleted事件处理程序应始终检查AsyncCompletedEventArgs.Error和AsyncCompletedEventArgs.Cancelled属性。如果引发了异常或操作被取消,则访问RunWorkerCompletedEventArgs.Result属性会引发异常。(http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx):