我有一个MVVM应用程序,它通过服务器上的XML加载数据。 XML随WebClient.DownloadStringAsync()
一起下载,然后由方法解析。问题是XML有点大,所以UI冻结了一段时间(2-3秒左右),而XML正在解析。
我解决此问题的想法是使用BackgroundWorker来处理解析。但是从我的DoWorkEventHandle
r调用的每个方法都在后台线程中运行吗?甚至是webclients事件处理程序?
整个解析事件发生在DownloadStringCompletedEventHandler
中,所以如果它不在后台线程中运行会有点无用。
感谢您的帮助,Stack Overflow到目前为止一直令人惊叹:)坚持下去!
答案 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)