我有一个MVVM应用程序,它通过服务器上的XML加载数据。XML使用WebClient.DownloadStringAsync()下载,然后由一个方法解析。问题是XML有点大,所以在解析XML时,UI会冻结一段时间(2-3秒左右)。
我解决这个问题的想法是使用BackgroundWorker来处理解析。但是,从我的DoWorkEventHandler调用的每个方法都在后台线程中运行吗?即使是webclients事件处理程序?
整个解析过程都是在一个DownloadStringCompletedEventHandler中进行的,所以如果不是在后台线程中运行,它就没有什么用处了。
谢谢你的帮助,Stack Overflow到目前为止已经很棒了:)保持下去!
发布于 2011-02-04 20:58:02
在使用来自BackgroundWorker的基于事件的异步模式组件时,您需要小心。特别是,如果它们是由BackgroundWorker.DoWork方法创建和启动的,那么它们将在ThreadPool线程而不是UI线程上引发事件。MSDN article published yesterday对这种情况进行了说明,并解释了为什么会发生这种情况。
如果从BackgroundWorker.DoWork (在ThreadPool线程上运行)调用WebClient.DownloadStringAsync,那么DownloadStringCompletedEventHandler将在ThreadPool线程上运行。但是,这可能是与BackgroundWorker线程不同的线程;并且BackgroundWorker可能在DownloadStringCompletedEventHandler启动时已经完成。
所以,我不会说它“在”BackgroundWorker中运行。相反,它是以一种自由线程的方式运行的。事件将在ThreadPool线程上激发,该线程可能与BackgroundWorker线程相同,也可能不同,当事件激发时,BackgroundWorker可能未完成,也可能未完成。
我认为更好的解决方案可能是让UI线程拥有WebClient,并让它的事件处理程序触发一个BackgroundWorker。这样,两个EAP组件都归UI线程所有,并将按预期运行。
发布于 2011-02-04 18:29:35
是的,据我所知,DoWorkEventHandler在一个单独的线程中触发。另外,还可以查看ThreadPool.QueueWorkItem等,这对你来说可能是一个更简单的过程。
发布于 2011-02-04 18:30:24
是的,这一切都在bgworker中运行。但你必须要小心。如果您更新绑定到视图的属性,并在您的bgworker中更新它们(当然还会引发NotifyPropertyChanged ),将会有一个异常!(因为您希望从UI线程中的另一个线程获取数据)。
https://stackoverflow.com/questions/4896903
复制相似问题