![](/img/trans.png)
[英]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.