[英]Async exception handling with void
我正在使用 Async CTP 編寫 IO 重型控制台應用程序。 但是我遇到了異常問題。
public static void Main()
{
while (true) {
try{
myobj.DoSomething(null);
}
catch(Exception){}
Console.Write("done");
//...
}
}
//...
public async void DoSomething(string p)
{
if (p==null) throw new InvalidOperationException();
else await SomeAsyncMethod();
}
並發生以下情況:“完成”被寫入控制台,然后我在調試器中得到異常,然后我按 continue my program exists 。
是什么賦予了?
如果您為您的控制台應用程序提供一個異步兼容的上下文(例如,我的 AsyncEx 庫中的AsyncContext
( docs , source )),那么您可以捕獲從該上下文傳播的異常,即使來自async void
方法:
public static void Main()
{
try
{
AsyncContext.Run(() => myobj.DoSomething(null));
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
Console.Write("done");
}
public async void DoSomething(string p)
{
if (p==null) throw new InvalidOperationException();
else await SomeAsyncMethod();
}
當您調用DoSomething()
時,它基本上會在后台創建一個Task
並啟動該Task
。 由於您的簽名void
,因此沒有Task
object 發回信號或您可以阻止,因此執行直接完成。 同時,該任務引發了一個異常,沒有人捕捉到,我懷疑這就是您的程序終止的原因。
我認為你想要的行為更像是這樣的:
public static void Main()
{
while (true) {
var t = myobj.DoSomething(null);
t.Wait();
if(t.HasException) {
break;
}
}
Console.Write("done");
//...
}
}
//...
public async Task DoSomething(string p)
{
if (p==null) throw new InvalidOperationException();
else await SomeAsyncMethod();
}
這將阻塞每個DoSomething
直到它完成並在DoSomething
拋出時退出循環。 當然,那么你並沒有真正做任何異步的事情。 但是從偽代碼中,我不能完全說出你想要異步發生的事情。
主要收獲:對異步方法使用void
意味着您失去了獲取異常的能力,除非您正在await
該異步方法。 作為同步調用,它基本上只是安排工作,結果消失在以太中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.