1 回答
TA贡献1830条经验 获得超9个赞
它不会编译
这是因为Task.Delay返回一个Task. 那里没有价值或例外。所以它不能直接与ResultOrException<T>.
您需要决定如何向呼叫者报告超时。如果你想要Task<ResultOrException<T>[]>错误,那么你可以这样做:
public async Task<ResultOrException<T>[]> WhenAllOrException<T>(IEnumerable<Task<T>> tasks)
{
var resultOrExceptions = Task.WhenAll(
tasks.Select(task => ...)
);
var delayTask = Task.Delay(2000);
var completedTask = await Task.WhenAny(resultOrExceptions, delayTask);
if (completedTask == delayTask)
throw new TimeoutException();
return await resultOrExceptions;
}
或者,如果你想返回一个数组ResultOrException<T>,每个数组都有超时错误,那么你可以这样做:
public async Task<ResultOrException<T>[]> WhenAllOrException<T>(IEnumerable<Task<T>> tasks)
{
var resultOrExceptionTasks = tasks.Select(task => ...)
.ToArray();
var resultOrExceptions = Task.WhenAll(resultOrExceptionTasks);
var delayTask = Task.Delay(2000);
var completedTask = await Task.WhenAny(resultOrExceptions, delayTask);
if (completedTask == delayTask)
return Enumerable.Repeat(new ResultOrException<T>(new TimeoutException()), resultOrExceptionTasks.Length).ToArray();
return await resultOrExceptions;
}
或者,如果您想返回及时到达的结果,并且只返回那些没有及时到达的结果的超时异常,那么您想要将内部WhenAny 移动WhenAll:
public Task<ResultOrException<T>[]> WhenAllOrException<T>(IEnumerable<Task<T>> tasks)
{
var delayTask = Task.Delay(2000);
return Task.WhenAll(tasks.Select(WithTimeout));
async Task<ResultOrException<T>> WithTimeout(Task<T> task)
{
var completedTask = await Task.WhenAny(task, delayTask);
if (completedTask == delayTask)
return new ResultOrException<T>(new TimeoutException());
try
{
return new ResultOrException<T>(await task);
}
catch (Exception ex)
{
return new ResultOrException<T>(ex);
}
}
}
旁注:您应该始终将 a 传递TaskScheduler
给ContinueWith
. 另外,我有一个可能有用的Try
实现。
- 1 回答
- 0 关注
- 155 浏览
添加回答
举报