簡體   English   中英

使用 void 處理異步異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM