BackgroundWorker:从DoWorkEventHandler调用的每个方法都在后台线程中运行吗?

时间:2011-02-04 10:25:55

标签: c# .net silverlight backgroundworker

我有一个MVVM应用程序,它通过服务器上的XML加载数据。 XML随WebClient.DownloadStringAsync()一起下载,然后由方法解析。问题是XML有点大,所以UI冻结了一段时间(2-3秒左右),而XML正在解析。

我解决此问题的想法是使用BackgroundWorker来处理解析。但是从我的DoWorkEventHandle r调用的每个方法都在后台线程中运行吗?甚至是webclients事件处理程序?

整个解析事件发生在DownloadStringCompletedEventHandler中,所以如果它不在后台线程中运行会有点无用。

感谢您的帮助,Stack Overflow到目前为止一直令人惊叹:)坚持下去!

3 个答案:

答案 0 :(得分:4)

使用BackgroundWorker中基于事件的异步模式(EAP)组件时需要小心。特别是,如果它们是由BackgroundWorker.DoWork方法创建并启动的,那么它们将在ThreadPool个线程而不是UI线程上引发它们的事件。 MSDN article published yesterday说明了这种情况并解释了为什么会发生这种情况。

如果您从WebClient.DownloadStringAsync(在BackgroundWorker.DoWork主题上运行)调用ThreadPool,则DownloadStringCompletedEventHandler将在ThreadPool主题上运行。但是,这可能是与<{1}}线程不同的线程;在BackgroundWorker开始时,BackgroundWorker 可能已经完成。

所以,我不会说它在DownloadStringCompletedEventHandler内“运行”。相反,它采用自由线程风格。该事件将在BackgroundWorker线程上触发,该线程可能与ThreadPool线程相同或不同,并且BackgroundWorker在事件触发时可能会或可能不会完成。

我认为更好的解决方案可能是保持UI线程拥有的BackgroundWorker,并使其事件处理程序启动WebClient。这样,两个EAP组件都由UI线程拥有,并且将按预期运行。

答案 1 :(得分:0)

是的,据我所知,DoWorkEventHandler在一个单独的线程中触发。另请查看ThreadPool.QueueWorkItem等,这对您来说可能是一个更简单的过程。

答案 2 :(得分:0)

是的,这一切都在bgworker中运行。但你必须要小心。如果更新绑定到视图的属性并在bgworker中更新它们(当然还会引发NotifyPropertyChanged),则会出现异常! (因为您希望从UI线程中的另一个线程获取数据)。