BackgroundWorker:从 DoWorkEventHandler 调用的每个方法是否都在后台线程中运行?
我有一个 MVVM 应用程序,它通过服务器上的 XML 加载数据。使用 WebClient.DownloadStringAsync()
下载 XML,然后通过方法进行解析。问题是 XML 有点大,因此在解析 XML 时 UI 会冻结一段时间(2-3 秒左右)。
我解决这个问题的想法是使用BackgroundWorker来处理解析。但是从我的 DoWorkEventHandle 调用的每个方法都在后台线程中运行吗?甚至网络客户端事件处理程序?
整个解析过程发生在 DownloadStringCompletedEventHandler
中,因此如果它不在后台线程中运行,它将毫无用处。
感谢您的帮助,Stack Overflow 到目前为止一直很棒:) 继续努力!
I have a MVVM application which loads data via a XML on a server. The XML is downloaded with WebClient.DownloadStringAsync()
and then is parsed by a method. The problem is that the XML is kind of big so the UI freezes for a while (2-3 seconds or so), while the XML is parsing.
My idea to solve this problem was to use a BackgroundWorker to handle the parsing. But does every method called from my DoWorkEventHandle
r run in the background thread? Even the webclients event handlers?
The whole parsing thing takes place in a DownloadStringCompletedEventHandler
so it would be kind of useless if that didn't run in a background thread.
Thanks for you help, Stack Overflow has been amazing so far :) Keep it up!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从
BackgroundWorker
使用基于事件的异步模式 (EAP) 组件时需要小心。特别是,如果它们是由 BackgroundWorker.DoWork 方法创建和启动的,那么它们将在 ThreadPool 线程而不是 UI 线程上引发事件。昨天发表的一篇MSDN 文章对此情况进行了说明,并解释了为什么会发生这种情况。如果您从
BackgroundWorker.DoWork
(在ThreadPool
线程上运行)调用WebClient.DownloadStringAsync
,则DownloadStringCompletedEventHandler
将在 ThreadPool 线程上运行。但是,这可能是与BackgroundWorker
线程不同的线程;并且在DownloadStringCompletedEventHandler
启动时,BackgroundWorker
可能已经完成。因此,我不会说它在
BackgroundWorker
“内部”运行。相反,它以自由线程的方式运行。该事件将在ThreadPool
线程上触发,该线程可能与BackgroundWorker
线程相同,也可能不同,并且BackgroundWorker
可能会或可能不会当事件触发时完成。我认为更好的解决方案可能是让 UI 线程拥有
WebClient
,并让其事件处理程序启动BackgroundWorker
。这样,两个 EAP 组件都归 UI 线程所有,并且将按预期运行。You need to be careful when using Event-based Asynchronous Pattern (EAP) components from a
BackgroundWorker
. In particular, if they are created and started by theBackgroundWorker.DoWork
method, then they will raise their events onThreadPool
threads rather than the UI thread. An MSDN article published yesterday has an illustration of this situation and an explanation of why this happens.If you call
WebClient.DownloadStringAsync
fromBackgroundWorker.DoWork
(which is running on aThreadPool
thread), thenDownloadStringCompletedEventHandler
will run on aThreadPool
thread. However, this may be a different thread than theBackgroundWorker
thread; and theBackgroundWorker
may have completed already by the time thatDownloadStringCompletedEventHandler
starts.So, I wouldn't say that it runs "within" the
BackgroundWorker
. Rather, it's acting in a free-threaded style. The event will fire on aThreadPool
thread which may or may not be the same as theBackgroundWorker
thread, and theBackgroundWorker
may or may not be complete when the event fires.I think a better solution may be to keep the
WebClient
owned by the UI thread, and have its event handler kick off aBackgroundWorker
. That way, both EAP components are owned by the UI thread and will behave as expected.是的,这一切都在 bgworker 中运行。但你必须小心。如果您更新绑定到视图的属性并在 bgworker 中更新它们(当然会引发 NotifyPropertyChanged),则会出现异常! (因为您想从 UI 线程中的另一个线程获取数据)。
yes, it all runs in the bgworker. But you have to be carefull. If you update properties which are bound to the view and you update them in your bgworker (and of course NotifyPropertyChanged is raised) there will be an exception! (Cause you want to get data from another thread in your UI Thread).
是的,据我了解,DoWorkEventHandler 在单独的线程中触发。另请查看 ThreadPool.QueueWorkItem 等,这对您来说可能是一个更简单的过程。
Yes as far as I understood, DoWorkEventHandler fires in a separate thread. Also check out ThreadPool.QueueWorkItem etc which might be a simpler process for you.