1
votes

I know that my goal can be achieved by using Task.WhenAny() but I will not deal with async await if I can avoid it, in order to prevent deadlocks. I have following code:

try
{
   Task.WaitAny(this.Tasks.ToArray());
   foreach (var task in this.Tasks)
   {
      if (task.IsFaulted || task.IsCanceled)
      {
         if (task.Exception.InnerException is OperationCanceledException)
         {

         }
      }
   }                    
}  
catch (OperationCanceledException o)
{
   // Handling cancelled tasks
}              
catch (Exception e)
{
   // Handling faulted tasks
}

And I for instance want to know exactly the id of my task, which has faulted or the Id of my task which has been cancelled. I have tried to do so as shown in the try block above, but this is not a solution since it also will throw an exception for tasks that has been cancelled before. Can I obtain a solution for this problem using Task.WaitAny() ?.

1
Synchronously waiting on asynchronous operation (by using WaitAny instead of WhenAny is exactly how you cause deadlocks. You avoid deadlocks by doing everything asynchronously all the way up the call stack. - Servy
But WaitAny is not an asynchronous operation as far as I know ? - Osman Esen
Correct. It's synchronously blocking on the asynchronous tasks that you have. That's how you go about getting into deadlocks. - Servy

1 Answers

4
votes

From the documentation of Task.WaitAny:

Return Value

Type: System.Int32

The index of the completed Task object in the tasks array.

So you can do this:

var taskIndex = Task.WaitAny(this.Tasks.ToArray());
var task = this.Tasks[taskIndex];