0

At any given time, my WPF application has a bunch of async Tasks running on background threads/synchronization contexts. At shutdown, I need to set a CancellationToken and then wait for these tasks to complete gracefully before I can start tearing down native libraries they depend on. But some of the tasks have continuations that (need to) run on the main thread, so calling Task.WaitAll(_myTasks) from the same thread will deadlock. What I'd like to do is something like this:

while(!AreAllTasksComplete(_myTasks))
   LetContinuationsThatAreWaitingForThisContextRun();
TearDownTheNativeLibraries();

But of course LetContinuationsThatAreWaitingForThisContextRun() does not exist. Is there any way to do what I'm trying to do? Do I need a completely different approach?

dlf
  • 9,045
  • 4
  • 32
  • 58
  • 1
    what about another background thread that watches your tasks while your main thread can return to the messageloop? maybe something awaitable... – DarkSquirrel42 Apr 21 '17 at 14:04
  • Its been a while sense I had to do a lot with tasks, but you may want to look at Task.WhenAll. This question explain a bit more about its uses.http://stackoverflow.com/questions/22699048/why-does-task-waitall-not-block-or-cause-a-deadlock-here – Hack Apr 21 '17 at 14:17
  • Since this is a WPF app, it turns out I can implement `LetContinuationsThatAreWaitingForThisContextRun()` like so: `Dispatcher.CurrentDispatcher.Invoke(() => { }, DispatcherProperity.Background`). This works (seemingly), but it relies on what is probably undocumented behavior. – dlf Apr 21 '17 at 17:39
  • 1
    @dlf, check [Cancelling a pending task synchronously on the UI thread](http://stackoverflow.com/q/20876645/1768303). – noseratio Apr 24 '17 at 00:20

1 Answers1

0

You can do

await Task.WhenAll(_myTasks);
TearDownTheNativeLibraries();
dvorn
  • 3,107
  • 1
  • 13
  • 12
  • Something like this was my first thought, but I need a way to prevent the app from exiting until after the continuation with TearDownTheNativeLibraries() runs. Otherwise the shudown process will continue while I'm awaiting, the application will exit, and TearDownTheNativeLibraries() will never happen, with the result that files they manage may be left in an inconsistent state. I may end up doing something like this, but it would take some refactoring. – dlf Apr 21 '17 at 15:01
  • This depends on (a) what event triggers the shutdown (e.g. button click) and (b) how you command system to terminate you (e.g. call Close() on main window). – dvorn Apr 21 '17 at 17:07