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

发布于 2024-10-16 06:05:43 字数 390 浏览 5 评论 0原文

我有一个 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 DoWorkEventHandler 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

合约呢 2024-10-23 06:05:43

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 the BackgroundWorker.DoWork method, then they will raise their events on ThreadPool 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 from BackgroundWorker.DoWork (which is running on a ThreadPool thread), then DownloadStringCompletedEventHandler will run on a ThreadPool thread. However, this may be a different thread than the BackgroundWorker thread; and the BackgroundWorker may have completed already by the time that DownloadStringCompletedEventHandler 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 a ThreadPool thread which may or may not be the same as the BackgroundWorker thread, and the BackgroundWorker 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 a BackgroundWorker. That way, both EAP components are owned by the UI thread and will behave as expected.

雅心素梦 2024-10-23 06:05:43

是的,这一切都在 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).

她比我温柔 2024-10-23 06:05:43

是的,据我了解,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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文