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 關注
- 233 瀏覽
添加回答
舉報