Reputation: 2929
In my case, I created tasks by:
IList<Task> Tasks = new List<Task>();
Tasks.Add(Task.Run(async () => { await functionAsync();}));
I need these tasks to run infinitely in order to continuously processing some incoming data. However, in cases when some fatal error/exceptions happen, I need to end the program by canceling all the tasks. I put together an simple example to simulate what I intended to do , but it does not work. I thought a task will considered to be end when throw an exception, and the WaitAny should return with AggregatedException, but it doesn't seem to be how it actually works. So, how can I make it correct?
public static void Main(string[] args)
{
Console.WriteLine(nameof(Main));
for (int i = 1; i < 5; i++)
{
var i1 = i;
_tasks.Add(Task.Run(async () => { await Tryme(i1); }));
}
try
{
Task.WaitAny(_tasks.ToArray());
}
catch (Exception e)
{
Console.WriteLine("Stop my program if any of the task in _tasks throw exception");
Console.WriteLine(e);
}
Console.ReadLine();
}
private static async Task Tryme(int i)
{
Console.WriteLine($"I'm {i}");
if (i == 3)
{
Console.WriteLine($"{i} is throwing the exception");
throw new Exception("fake one");
}
await Task.Delay(TimeSpan.MaxValue);
}
Upvotes: 1
Views: 199
Reputation: 2929
Got some clue from this post . It looks that WaitAny will not throw any exception. I got the exception by:
int faultIndex = Task.WaitAny(_tasks.ToArray());
if (_tasks[faultIndex].IsFaulted)
{
Console.WriteLine($"{faultIndex} end");
throw _tasks[faultIndex].Exception;
}
Upvotes: 0
Reputation: 149518
Instead of manually canceling the entire task-chain, you can use TPL Dataflow which falts the entire block for you if an unhandeled exception occurs, or can be configured to behave in other modes if needed:
var actionBlock = new ActionBlock<int>(i => TryMe(i));
foreach (var num in Enumerable.Range(0, 100))
{
actionBlock.Post(num);
}
try
{
await actionBlock.Completion();
}
catch (Exception e)
{
// Block finished prematurely, handle exception.
}
Note Dataflow takes care of parralisation for you, no need to manually create tasks.
Upvotes: 3