我调用一个异步方法,而该方法又调用需要启动几个异步操作。
完成所有异步操作后,我需要通知调用方操作是否已完成或取消。代码如下所示。它似乎可以工作,直到它因FatalExecutionEngineError而崩溃。我不进行任何 P/调用或不安全的调用。
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;
}
}
错误消息显示
运行时遇到致命错误。错误的地址 在0x6c108144,在线程0xd94上。错误代码为0xc0000005。这 错误可能是 CLR 中的错误,也可能是不安全或不可验证的错误 部分用户代码。此错误的常见来源包括用户 COM 互操作或 PInvoke 的封送处理错误,这可能会损坏 叠。
怎么可能等到所有任务都完成,或者等到它们被取消,然后返回一个值,指示它们是完成还是被取消?
FatalExecutionEngineError
听起来像是CLR错误。请开发一个最小的重现,并通过Microsoft连接将其报告给Microsoft。
最好让取消按照设计的方式进行(通过例外(。要await
多个任务,请使用 Task.WhenAll
。
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);
}
try
{
await Task.WhenAll(currentlyRunningTasks);
return true;
}
catch (OperationCanceledException)
{
return false;
}
}
private async Task FetchForItem(ItemsBoundToUI channel, CancellationToken src)
{
var subitems = await dataRepository.GetSubItemsAsync(channel.ID);
src.ThrowIfCancellationRequested();
channel.SubItems = subitems;
}
}