简体   繁体   English

我如何等待BackgroundWorker完成?

[英]How do I wait for a BackgroundWorker to complete?

I have read the answers from How to wait for a BackgroundWorker to cancel? 我已经阅读了如何等待BackgroundWorker取消的答案 , but I couldn't find a solution to my specific problem: ,但找不到针对我特定问题的解决方案:

My app has to load a large amount of data, but in most cases this data won't be required immediately after the app has started. 我的应用程序必须加载大量数据,但是在大多数情况下,应用程序启动后并不需要立即提供此数据。

To minimize the delay when the user actually requests the data, I load it using a BackgroundWorker, which launches when the app starts. 为了最大程度地减少用户实际请求数据时的延迟,我使用BackgroundWorker加载了该数据,它在应用启动时启动。 Hopefully, when the user requests the data, the BackgroundWorker has completed. 希望当用户请求数据时,BackgroundWorker已完成。

In some cases, however, it might not have. 但是,在某些情况下,可能没有。 In these cases I want to wait for the loading to complete before showing anything to the user. 在这些情况下,我想等待加载完成,然后再向用户显示任何内容。

All the techniques I can think of have race conditions: for example, if I set up an AutoResetEvent , I can't use WaitOne() when the user requests the data, because the AutoResetEvent might already have signaled; 我能想到的所有技术都有竞争条件:例如,如果我设置了AutoResetEvent ,那么当用户请求数据时我就不能使用WaitOne() ,因为AutoResetEvent可能已经发出信号了; if I add a boolean loading_complete flag and check it before calling WaitOne, loading_complete might be set to true after the ckecing, but before the WaitOne call, which will never return... 如果我在调用WaitOne之前添加了一个布尔loading_complete标志并对其进行了检查,则在loading_complete之后但在WaitOne调用之前, loading_complete可能会设置为true,它将永远不会返回...

Any idea? 任何想法?

EDIT : Thanks to @500-InternalServerError for the solution; 编辑 :感谢@ 500-InternalServerError为解决方案; using a ManualResetEvent works great. 使用ManualResetEvent效果很好。 Thanks to everyone else for the suggestions. 感谢其他人的建议。

一旦在WorkCompleted事件处理程序中完成BackgroundWorker,就可以放置将发生的一切

Use a simple mutex locked by BackgroundWorker , and have any other threads waiting for completion to acquire and release it. 使用由BackgroundWorker锁定的简单互斥锁,并使任何其他线程等待完成获取并释放它。 Once BackgroundWorker is done, have it release the lock, and all other threads should be able to continue their work. 一旦BackgroundWorker完成,让它释放锁,所有其他线程应该能够继续其工作。

There might be some specific C# way of doing this (I think the Monitor class might be handy). 可能有一些特定的C#方式(我认为Monitor类可能很方便)。

Update: In fact, the object needed to solve the problem is a form of condition variable working as a latch, and, as mentioned by OP, ManualResetEvent covers that specific need. 更新:实际上,解决问题所需的对象是作为变量的形式的条件变量,如OP所述, ManualResetEvent了这一特定需求。

Background worker supports RunWorkerCompleted event. 后台工作者支持RunWorkerCompleted事件。 This event can be used to determine if the loading has finished or not. 此事件可用于确定加载是否已完成。

There are two conditions 有两个条件

  • User has requested data after the worker has completed. 工作者完成后,用户已请求数据。

To make the things less complicated, you can add a boolean member variable which will be set to false when the background worker starts loading data. 为了简化操作,您可以添加一个布尔成员变量,该变量将在后台工作程序开始加载数据时设置为false。 Once the data is loaded, the runworkercompleted event will fire which will set the variable to true which will help you determine if the data is loaded or not. 加载数据后,将触发runworkercompleted事件,该事件会将变量设置为true,这将帮助您确定是否加载了数据。

  • User has requested data before worker is completed (can be determined from the above stated bool variable) and waiting for the data to load. 用户在工作程序完成之前可以请求数据(可以从上述bool变量确定)并等待数据加载。

When the user request the data, you can set a flag/another bool variable such as 当用户请求数据时,您可以设置标志/另一个布尔变量,例如

WaitingForData = true; WaitingForData = true;

when the RunWorkerCompleted event is fired, it will check for the status of WaitingForData and if it is true, it will display the data. 触发RunWorkerCompleted事件时,它将检查WaitingForData的状态,如果为true,则将显示数据。 This way, you will not need to wait for the thread completion. 这样,您将不需要等待线程完成。

Using this method will help you avoid any race condition or inter thread communication. 使用此方法将帮助您避免任何竞争情况或线程间通信。

Use a boolean flag, set it to true in the background worker completed event handler. 使用布尔值标志,在后台工作程序完成的事件处理程序中将其设置为true。

When you need to check whether the data is loaded just check the variable. 当您需要检查是否已加载数据时,只需检查变量即可。

Make sure you lock it before trying to access it to avoid the race condition. 在尝试访问它之前,请确保已将其锁定,以避免出现竞争情况。

If the data is not ready when it is requested, you could add another event handler at that point to the background worker completed event, which does what needs to be done with the data. 如果在请求数据时数据尚未准备就绪,则可以在此时将另一个事件处理程序添加到后台工作程序已完成事件中,该事件处理程序需要处理数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM