[英]How do I call asynchronous method returning void from synchronous method in C# and be sure async method is finished?
[英]How to convert a void synchronous method to async method?
所以我有这个只有同步操作的方法:
public void Foo(){
//do something synchronously
if(x == 0)
return;
else if(x < 5):
//do something
return;
// do something extra
}
由于一些接口更改,该方法必须更改为异步,尽管没有异步操作。 为了拥有 async 关键字,它的主体中必须有一个await
关键字。 原始同步方法的等效方法是:
public async Task FooAsync(){
//do something synchronously
if(x == 0)
await Task.CompletedTask;
else if(x < 5):
//do something
await Task.CompletedTask;
// do something extra
}
我不确定这一点,因为CompletedTask
属性表明它是一个成功的操作,但并非所有这些条件都是如此。
编辑:在评论中解决。 仅仅因为一个方法用“async”后缀表示,并不意味着它需要一个async
修饰符。 function 将按如下所示编写以遵守接口更改:
public Task FooAsync(){
//do something synchronously
if(x == 0)
return Task.CompletedTask;
else if(x < 5):
//do something
return Task.CompletedTask;
// do something extra
return Task.CompletedTask;
}
正如其他人所指出的,类似任务的返回类型是异步签名,而async
是异步实现细节。 完全有可能让Task
返回方法不是async
。
但是,有一个重要的警告:例外。 当异步(即类似Task
返回)方法失败时,预期的语义是捕获异常并将其放置在返回的任务上。
因此,您不想只返回CompletedTask
; 您还想捕获异常并使用Task.FromException
:
public Task FooAsync()
{
try
{
//do something synchronously
if(x == 0)
return Task.CompletedTask;
else if(x < 5):
//do something
return Task.CompletedTask;
// do something extra
return Task.CompletedTask;
}
catch (Exception ex)
{
return Task.FromException(ex);
}
}
在这一点上,有相当多的样板。 您可能更喜欢使用async
而不使用await
,例如:
#pragma warning disable 1998
public async Task FooAsync()
#pragma warning restore 1998
{
//do something synchronously
if(x == 0)
return;
else if(x < 5):
//do something
return;
// do something extra
}
这种方法的问题是你会得到编译器警告,除非你包含丑陋的编译指示来禁用它们。 如果您发现自己需要在多个地方执行此操作,我建议您使用一些辅助方法( 从我的 AsyncEx 库中窃取):
public static class TaskHelper
{
#pragma warning disable 1998
public static async Task ExecuteAsTask(Action func)
#pragma warning restore 1998
{
func();
}
#pragma warning disable 1998
public static async Task<T> ExecuteAsTask<T>(Func<T> func)
#pragma warning restore 1998
{
return func();
}
}
像这样使用:
public Task FooAsync() => TaskHelper.ExecuteAsTask(() =>
{
//do something synchronously
if(x == 0)
return;
else if(x < 5):
//do something
return;
// do something extra
});
它允许您快速轻松地包装同步方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.