简体   繁体   中英

How do I wait for a BackgroundWorker to complete?

I have read the answers from How to wait for a BackgroundWorker to cancel? , 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. Hopefully, when the user requests the data, the BackgroundWorker has completed.

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; 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...

Any idea?

EDIT : Thanks to @500-InternalServerError for the solution; using a ManualResetEvent works great. 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. Once BackgroundWorker is done, have it release the lock, and all other threads should be able to continue their work.

There might be some specific C# way of doing this (I think the Monitor class might be handy).

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.

Background worker supports RunWorkerCompleted event. 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. 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.

  • User has requested data before worker is completed (can be determined from the above stated bool variable) and waiting for the data to load.

When the user request the data, you can set a flag/another bool variable such as

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. 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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