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