gpt4 book ai didi

c# - 按顺序运行任务 : how to deal with exceptions?

转载 作者:行者123 更新时间:2023-11-30 15:30:20 47 4
gpt4 key购买 nike

根据 svick 的建议我创建了一个小类,其目的是按顺序运行任务,也就是说,它在 ThreadPool 上安排它们,但它确保它们按照提交的顺序一个接一个地执行。它看起来像这样:

class SequentialTaskRunner<TResult> where TResult : new() {

public Task<TResult> Run(Func<TResult> func) {
var result = RunInternal(func, m_previous);
m_previous = result;
return result;
}

async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous) {
await previous;
return await Task.Run(func);
}

Task<TResult> m_previous = Task.FromResult(new TResult());
}

现在,我遇到的问题是,如果 func() 抛出异常,那么 Run() 的每次后续调用也将返回该异常,并且无法运行新任务。我试过像这样更改 RunInternal:

async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous) {
if (previous.Exception == null) {
await previous;
}
return await Task.Run(func);
}

但这并不可靠;如果快速提交任务,一个任务的失败仍然会导致多个任务返回相同的异常。我对为什么感到困惑,并希望得到解释。我刚刚开始使用 async/await 顺便说一句。

最佳答案

您的代码之所以不起作用,是因为您几乎是在要求它预测 future 。

Task 尚未完成时,其 Exception 将始终为 null。这意味着您的 await previous 很可能会抛出异常。

这里最简单的解决方案是使用通用的catch:

async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous)
{
try
{
await previous;
}
catch {}

return await Task.Run(func);
}

如果您想隐藏那个空的 catch(因为这通常是一种不好的做法),或者如果您经常这样做并希望避免重复,您可以为此编写一个辅助方法:

public static async Task IgnoreException(this Task task)
{
try
{
await task;
}
catch {}
}

用法:

async Task<TResult> RunInternal(Func<TResult> func, Task<TResult> previous)
{
await previous.IgnoreException();
return await Task.Run(func);
}

关于c# - 按顺序运行任务 : how to deal with exceptions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22273055/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com