C# 如何将无效的同步方法转换为异步方法?
所以我有一个方法,它只有同步操作:C# 如何将无效的同步方法转换为异步方法?,c#,async-await,C#,Async Await,所以我有一个方法,它只有同步操作: public void Foo(){ //do something synchronously if(x == 0) return; else if(x < 5): //do something return; // do something extra } 我不确定这一点,因为CompletedTask属性表明它是一个成功的操作,但并非所有这些条件都是如此 编辑:在注释中
public void Foo(){
//do something synchronously
if(x == 0)
return;
else if(x < 5):
//do something
return;
// do something extra
}
我不确定这一点,因为CompletedTask
属性表明它是一个成功的操作,但并非所有这些条件都是如此
编辑:在注释中解析。仅仅因为方法用“async”后缀表示,并不意味着它需要async
修饰符。该函数将按如下所示编写,以遵守接口更改:
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;
}
公共任务fooancy(){
//同步做某事
如果(x==0)
返回Task.CompletedTask;
否则,如果(x<5):
//做点什么
返回Task.CompletedTask;
//做些额外的事
返回Task.CompletedTask;
}
正如其他人所指出的,类似于任务的返回类型是异步签名,而
async
是异步实现细节。完全可能有一个任务
-返回方法不是异步
然而,有一个重要的警告:例外。当异步(即,任务
-like返回)方法失败时,预期的语义是捕获异常并将其放在返回的任务上
因此,您不希望只返回CompletedTask
;您还需要捕获异常并使用任务。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);
}
}
这种方法的问题是,除非包含丑陋的pragmas来禁用编译器警告,否则会收到编译器警告。如果您发现自己需要在多个地方执行此操作,我建议使用一些helper方法():
公共静态类TaskHelper
{
#布拉格警告禁用1998
公共静态异步任务ExecutEastTask(操作函数)
#布拉格警告恢复1998
{
func();
}
#布拉格警告禁用1998
公共静态异步任务执行任务(Func Func)
#布拉格警告恢复1998
{
返回func();
}
}
这样使用:
public Task FooAsync() => TaskHelper.ExecuteAsTask(() =>
{
//do something synchronously
if(x == 0)
return;
else if(x < 5):
//do something
return;
// do something extra
});
public Task fooancy()=>TaskHelper.executeEastTask(()=>
{
//同步做某事
如果(x==0)
返回;
否则,如果(x<5):
//做点什么
返回;
//做些额外的事
});
它允许您快速轻松地包装同步方法。仅仅因为接口要求它返回任务,并不意味着它必须标记为异步。您可以不将其标记为async,让返回类型为Task,然后
返回Task.CompletedTask
。只需返回Task.CompletedTask
,就可以了。忘记async
和await
No….仅仅因为接口用-async后缀声明方法名称并不意味着它必须标记为async。不需要时将其标记为异步只会引入不必要的状态机。@avhh该接口只会指示它返回一个任务
。只有当您必须使用await
时,才需要使用async
关键字;如果您的某些代码应该在异步调用后运行,则只需要使用await
关键字,这与您的代码不同。您可能会发现这很有趣:。省略async/await将在出现异常时更改方法的行为。再次抱歉;),正在用任务包装异常。FromException
建议仅满足抛出异常的异步等待“契约”?@Basin:这更像是一个返回契约的任务,而不是一个async
/等待
契约。是的,它提供了预期的语义。
#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
}
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
});