I need some help with TPL and Tasks
Here are my scenarios:
I have a few event handlers that spawn tasks. If an event is invoked before its previous task is completed, I want to wait (block) it before proceeding.
I have a synchronous method that, when invoked, must wait until any spawned tasks from any event handlers are done, before proceeding.
public void DoSomething()
{
// Expects any running tasks from OnEvent1(), OnEvent2(), OnEvent3()
// to be completed before proceeding.
}
public void OnEvent1()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent2()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent3()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
An actual scenario would be:
- OnFetchData() => Spawns task. All subsequent calls to this needs to be queued.
OnSyncSettings() => Spawns task. All subsequent calls to this needs to be queued.
OnAutoBackup() => Synchronous method. Wait for any other tasks (e.g, Fetch data/Sync settings) to complete before saving.
- OnFullBackup() => Synchronous method. Manually runs FetchData() and SyncSettings(), waits for completion, proceed.
My question is simply: How can I do this?
Would this approach be correct?
Each event handler remembers its last . When invoked, it'll wait for all tasks in its list to complete before proceeding.
For the synchronous method, it needs to wait for all tasks (From every event handler) to
Task _lastEvent1Task;
public void OnEvent1()
{
// Wait for all tasks to complete before proceeding
if (_lastEvent1Task!=null)
_lastEvent1Task.Clear();
// Spawns new task
_lastEvent1Task = Task.Factory.StartNew(()=>{ });
}
public void OnEvent3()
{
// Wait for any running tasks to complete before proceeding
if (_lastEvent1Task != null) _lastEvent1Task.Wait();
if (_lastEvent2Task != null) _lastEvent2Task.Wait();
...
// Proceed
}
Thanks!
[Edit]
When DoSomething() is waiting and Event1 is raised? What if DoSomething() is running and an event is raised?
OnEvents()
- If first task: Spawns task and execute asynchronously
- If previous task still running, queue/block. Critical section.
- Assume:
- These events typically not raised multiple times.
- The UI is expected to prevent user from raising the same event while still running.
DoSomething() (when called)
- Assume: Event notifications are disabled.
- Assume: No new events will be queued.
- Expected: to wait until all remaining queued tasks are completed before proceeding
- Expected: to be a synchronous call, and does not return to caller until executed through
DoSomething()
is waiting andEvent1
is raised? Should the event code wait untilDoSomething()
is complete? Or shouldDoSomething()
wait for the new event too? What ifDoSomething()
is running and an event is raised? – svick