-1

According to one of the comments on a previous question the following code may deadlock.

var task1 = myFunction1Async();
var task2 = myFunction2Async();
Task.WaitAll(task1, task2);

Is this true?

If it is, then one of the main benefits of TPL (easily handling multiple I/O calls that may block) seems to go out of the window.

Neil
  • 11,059
  • 3
  • 31
  • 56
  • Deadlocks occur when threads that are supposed to be used for continuing after a task aren't available because they're waiting on that very same task (directly or indirectly). Whether you await one or many tasks isn't relevant -- what's relevant is how your tasks have been configured to continue (`.ConfigureAwait(false)`). If there is a deadlock already between `task1` and `task2`, this code isn't going to be in a position to solve it (but it may be able to avoid it by explicitly reconfiguring). – Jeroen Mostert Oct 16 '19 at 11:32
  • 1
    You already asked this. Deadlocks are caused by *blocking* and this call blocks. You haven't provided *any information* about your code so the only answer is `possibly, if the code is written in a way that allows deadlocks`. Use `await Task.WhenAny()` instead of blocking – Panagiotis Kanavos Oct 16 '19 at 11:35
  • 1
    A way *any* blocking code can cause deadlocks, is if it starts a task or thread from the UI that internally uses `.Invoke()` to update the UI, but then *blocks* with `Task.WaitAll()`, `Task.Wait()`, or by blocking on a semamphore or event. `Invoke` will try to run on the UI thread, which is blocked and thus it will never finish, thus never allowing the UI thread to proceed – Panagiotis Kanavos Oct 16 '19 at 11:39
  • If `myFunction1Async` and `myFunction2Async` are totally async, use `.ConfigureAwait(false)` on every async function call, and the only use of the result is after BOTH tasks have finished, then will it still deadlock? – Neil Oct 16 '19 at 11:40
  • 3
    You can't put `ConfigureAwait` on *WaitAll*. Why those questions? Why not use the proper code? `await Task.WhenAll(...)` ? Put the reason in the question itself. Even properties can be async if handled properly - they could return a `Lazy` for example – Panagiotis Kanavos Oct 16 '19 at 11:42
  • 1
    Let `WaitAll` *rest in peace*, `await Task.WhenAll(task1, task2);` – Dmitry Bychenko Oct 16 '19 at 11:45

1 Answers1

1

I believe the confusion is that Task.WaitAll is the synchronous version of the (better) Task.WhenAll method. Here's an SO post covering the distinctions between the two.

All the comment on the referenced post was trying to say is that synchronously waiting for many tasks results in the same sort of deadlocks as waiting on one task.

chill94
  • 341
  • 1
  • 5