c# – 使用任务重试异步函数 – 哪种方法更有效?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用任务重试异步函数 – 哪种方法更有效?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2329字,纯文字阅读大概需要4分钟。
内容图文
![c# – 使用任务重试异步函数 – 哪种方法更有效?](/upload/InfoBanner/zyjiaocheng/794/107ba25ada7646b8a684a215ada81a2b.jpg)
我想知道哪种方法在内存和资源使用方面更有效率.
特别是方法#1,我很难想象如何创建任务对象和线程旋转?有人可以详细解释一下详细介绍的内容吗?
如果两者之间没有区别(我想避免冒泡异步),我想使用#1.对于#2,我理解编译器将在下面生成一个状态机并返回. OTOH,#1在概念上似乎是递归的,但在传统意义上它是递归的,就像在一个堆栈帧中等待另一个?
方法#1:
internal static Task ExecuteAsyncWithRetry(Func<Task> methodToExecute, Func<bool> shouldRetry)
{
var tcs = new TaskCompletionSource<object>();
try
{
return methodToExecute().ContinueWith<Task>((t) =>
{
if (t.IsFaulted || t.IsCanceled)
{
if (shouldRetry())
{
return ExecuteAsyncWithRetry(methodToExecute, shouldRetry);
}
else
{
tcs.SetException(t.Exception);
}
}
else
{
tcs.SetResult(null);
}
return tcs.Task;
}, TaskContinuationOptions.ExecuteSynchronously).Unwrap();
}
catch(Exception ex)
{
tcs.SetException(ex);
}
return tcs.Task;
}
方法#2(忽略两者之间异常传播的差异):
internal static async Task ExecuteWithRetry(Func<Task> methodToExecute, Func<bool> shouldRetry)
{
while (true)
{
try
{
await methodToExecute();
}
catch(Exception ex)
{
if(!shouldRetry())
{
throw;
}
}
}
}
解决方法:
除了不同的例外和取消传播,还有另一个主要区别.
在第一种情况下,由于TaskContinuationOptions.ExecuteSynchronously,您的continuation在任务完成的同一线程上运行.
在第二种情况下,它将在原始同步上下文上运行(如果在具有同步上下文的线程上调用了methodToExecute).
尽管第一种方法可能更有效,但也可能难以理解(特别是当您或其他人在一年内返回时).
我将遵循KISS principle并坚持使用第二个修正案:
await methodToExecute().ConfigureAwait(false);
更新以解决评论:
“OTOH, #1 seems recursive conceptually but will it be recursive in the
traditional sense as in one stack-frame waiting on the other?”
对于#1,它是在同一堆栈帧上递归发生,还是在不同堆栈帧上异步发生,完全取决于methodToExecute内部的内容.在大多数情况下,如果在methodToExecute中使用一些自然的异步API,则不会有传统的递归.例如,HttpClient.GetStringAsync completes on a random IOCP pool thread和Task.Delay在随机工作线程线程上完成.
但是,即使异步API也可以在同一个线程上同步完成(例如MemoryStream.ReadAsync或Task.Delay(0)),在这种情况下会有递归.
或者,在methodToExecute中使用TaskCompletionSource.SetResult也可以触发同步延续.
如果你真的想避免任何递归的可能性,请通过Task.Run(或Task.Factory.StartNew / Task.Unwrap)调用methodToExecute.或者,更好的是,删除TaskContinuationOptions.ExecuteSynchronously.
对于#2,即使在初始线程上存在同步上下文,也可以使用相同的场景.
内容总结
以上是互联网集市为您收集整理的c# – 使用任务重试异步函数 – 哪种方法更有效?全部内容,希望文章能够帮你解决c# – 使用任务重试异步函数 – 哪种方法更有效?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。