I call an async method which in turn calls needs to start several async opertions.
Once all the async operations are finished, I need need notify the caller whether the operations were completed or canceled. The code can be seen below. It seemingly works until it crashes with an FatalExecutionEngineError. I do not make any P/invoke or unsafe calls.
public class Fetcher
{
private List<ItemsBoundToUI> uiItems;
public async Task<bool> Fetch()
{
List<Task> currentlyRunningTasks = new List<Task>();
var src = new CancellationTokenSource();
foreach (var channel in this.uiItems)
{
var task = FetchForItem(channel, src.Token);
currentlyRunningTasks.Add(task);
}
bool wasCancelled = await Task.Factory.ContinueWhenAll(currentlyRunningTasks.ToArray(),
(s) =>
{
bool wasC = s.Any(ss => ss.IsCanceled);
return wasC;
}
);
return !wasCancelled;
}
private async Task FetchForItem(ItemsBoundToUI channel, CancellationToken src)
{
var subitems = await dataRepository.GetSubItemsAsync(channel.ID);
if (src.IsCancellationRequested)
return;
channel.SubItems = subitems;
}
}
The error message says
The runtime has encountered a fatal error. The address of the error
was at 0x6c108144, on thread 0xd94. The error code is 0xc0000005. This
error may be a bug in the CLR or in the unsafe or non-verifiable
portions of user code. Common sources of this bug include user
marshaling errors for COM-interop or PInvoke, which may corrupt the
stack.
How is it possible to wait until all the tasks have finished, or until they are cancelled and then return a value indicating whether they finished or were cancelled?
The
FatalExecutionEngineErrorsounds like a CLR bug. Please develop a minimal repro and report it to Microsoft via Microsoft Connect.It’s best to let cancellation work the way it was designed (via exceptions). To
awaitmultiple tasks, useTask.WhenAll.