gpt4 book ai didi

c# - 重试上一个任务操作 TPL

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:49 24 4
gpt4 key购买 nike

我想实现一个重试任务,该任务采用之前失败的任务操作并重复它。

这就是我目前所拥有的。然而,它只是重复任务出错的事实,而不是再次触发任务的操作。

public static async Task<T> Retry<T>(this Task<T> task, int retryCount, int delay, TaskCompletionSource<T> tcs = null)
{
if (tcs == null)
{
tcs = new TaskCompletionSource<T>();
}

await task.ContinueWith(async _original =>
{
if (_original.IsFaulted)
{
if (retryCount == 0)
{
tcs.SetException(_original.Exception.InnerExceptions);
}
else
{
Console.WriteLine("Unhandled exception. Retrying...");

await Task.Delay(delay).ContinueWith(async t =>
{
await Retry(task, retryCount - 1, delay, tcs);
});
}
}
else
tcs.SetResult(_original.Result);
});
return await tcs.Task;
}

我试着用一点思考来完成 Action 。然而,一旦任务完成,操作似乎设置为空。

var action = task
.GetType()
.GetField("m_action", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(task) as Action;

理想情况下,我希望我的实现看起来像这样:

try
{
await MakeFailure().Retry(5, 1000);
}
catch (Exception ex)
{
Console.WriteLine("I had an exception");
}

这可能是不可能的,但我想在将代码重构为 Retry(Func<T> task) 之前确定一下

最佳答案

Not completely against it. But it changes the flow of the code to a fault first layout which I don't like

考虑您的类型。 Task表示一个异步操作。在异步世界中,Task表示一个异步操作已经开始Task不是您可以“重试”的东西。

另一方面,Func<Task>表示可以启动的异步操作。或者重新启动。这就是您需要处理的问题。

一旦您使用了适当的类型,代码就很简单了:

public static async Task<T> Retry<T>(Func<Task<T>> action, int retryCount, int delay)
{
while (retryCount > 0)
{
try
{
return await action().ConfigureAwait(false);
}
catch (Exception ex)
{
await Task.Delay(delay).ConfigureAwait(false);
--retryCount;
}
}
return await action().ConfigureAwait(false);
}

与其他回答者一样,我建议您使用实际上为此设计的库。 Transient Fault Handling Application BlockPolly是两个很好的例子。

关于c# - 重试上一个任务操作 TPL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32214684/

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