[英]How do I call asynchronous method returning void from synchronous method in C# and be sure async method is finished?
我搜索了StackOverflow,但沒有找到針對我的特定情況的明確答案。 我有一個方法:
public async Task InitializeMachine()
{
await DoSomeWork1();
// other stuff
await DoSomeWork2();
// other stuff
}
請注意,它返回的簽名是Task
,而不是Task<T>
。 這將很困難(如果不是不可能重寫所有這樣的方法。我想從同步方法中調用此方法,並讓它等待InitializeMachine方法完全完成。同樣,很難將其更改為異步方法(下面我將為感興趣的人介紹為什么)。我研究了一些相關的問題和參考,例如:
https://msdn.microsoft.com/zh-CN/magazine/mt238404.aspx和
答案似乎很舊(也許有一種更好的新方法?),至少在許多情況下,它們似乎取決於返回Task<T>
的異步方法,而不僅僅是Task
。 我有
void Initialize()
{
//InitializeMachine(); // Perfectly legal, but will return at first await
//return Task.Run(() => InitializeMachine()).GetAwaiter().GetResult(); // can't get this to compile. My typo? Or because it's Task not Task<T> ? This is the "Thread Pool Hack" in first reference above by Stephen Cleary
var task = Task.Run(() => InitializeMachine()); // these 2 lines work!
task.Wait(); // but see heated argument in 2nd reference in the answer by Herman Schoenfeld. Is it safe?
Task task = Task.Run(async () => await InitializeMachine()); // also works. Comes from 3rd reference by author "Tohid"
}
有人可以告訴我應該使用哪種方法,為什么? 就像我說的那樣,我嘗試進行研究,但是發現自己對為什么存在潛在的僵局和其他問題的所有爭論都有些失落。 所有的分歧加劇了我的困惑。 當然,到2018年有確定的方法嗎?
謝謝戴夫
PS對於那些在乎的人,我正在使用SMC狀態機庫。 參見: https : //sourceforge.net/projects/smc/簡要地說,狀態機代碼是從文本文件自動生成的。 但是生成的代碼是同步方法。 是的,我可以破解生成的代碼(但是它將被覆蓋)或重新考慮整個問題(也許InitializeMachine不應該通過異步發送),但是我的問題仍然存在。 在我看來,有時候同步方法需要調用異步方法,它們應該等到異步方法完成!
您應該使用此:
InitializeMachine().GetAwaiter().GetResult();
這將確保在InitializeMachine
引發的任何異常都不會包裝到AggregateException
。 請注意,不需要return
語句,因為您不返回任何內容( void
方法)。
編輯
由於您使用的是WPF,所以最好保持異步所有模式:
public async void InitializeMachineAsync()
{
await DoSomeWork1().ConfigureAwait(false);
await DoSomeWork2().ConfigureAwait(false);
}
InitializeMachineAsync
可以是任何事件(例如Window_Load
)
最簡單的事情是
InitializeMachine().Wait();
關於異常處理有一些注意事項
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.