How to make a task wait until other task wakes it up (or timeout)

xander7b

New member
Joined
Jan 31, 2013
Messages
1
Programming Experience
1-3
Without risking the case of the 2 tasks running on the same thread and having them both stopped.

I want the first task to wait until another task finishes some action. After the second task is done with its action, it should wake the first task up and continue working from where it stopped. The first task should be waked up as well if the first task didn't do the action after a certain time.

Now, the major problem I am having is that since both are tasks, not threads, most solutions I found looks like they stop the thread, not the task only. So, it could be the case that both tasks be running on the same thread, and thus when I make the first task wait, both wait and it timeouts anyway.

Is there a clean solution around this ?

Thanks;
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,272
Location
Sydney, Australia
Programming Experience
10+
If you're talking about tasks as in System.Threading.Tasks.Task or .Task<TResult> objects then they will never be executed on the same thread. Those classes use the ThreadPool, so each task is queued until a thread pool thread becomes available. When a thread is designated for a task, it will only be used for something else when that task completes.

What you should do is use a WaitHandle, i.e. an AutoResetEvent or a ManualResetEvent. You call WaitOne in the task that needs to be paused and optionally specify a timeout period. That task will then wait at that method until the WaitHandle is signalled or the timeout expires. You then call Set in the second task to signal the first that it may continue.

If you're only going to call Set once then it doesn't really matter whether you use an AutoResetEvent or a ManualResetEvent. In both cases, calling Set opens the gate so any waiting threads can proceed. In the case of an AutoResetEvent, the gate is closed immediately that a thread passes through the gate so subsequent threads will have to wait for Set to be called again. In the case of a ManualResetEvent, the gate remains open and allows all waiting threads to proceed, as well as any that start waiting after Set was called, until you explicitly call Reset. Basically, both types act as a gate that needs to be opened to allow threads to pass through but one stays open when you open it and must be explicitly closed while the other must be explicitly opened for each and every thread that wants to pass.
 
Last edited:

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
897
Location
Norway
Programming Experience
10+
Task.ContinueWith sounds like it, but you need a timeout. Since you use .Net 4.5 you can probably arrange that with Task.WhenAny and Task.Delay. The first task probably needs to be cancelled after timeout too.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,272
Location
Sydney, Australia
Programming Experience
10+
While I keep intending to, I've never actually spent any time to learn the tasks library at any more than a superficial level. WaitHandles are how you synchronise threads but the purpose of the tasks library is to wrap all the complexity of multi-threading and expose a simple interface, or at least as simple as it can be for such complex functionality. With that in mind, it makes sense that the tasks library would provide methods such as those mentioned by JohnH to accomplish this sort of thing. Presumably they use WaitHandles under the hood but you would not need to concern yourself with that. Maybe I'll allocate some time this weekend to learn this stuff properly.
 
Top Bottom