2013-04-04 79 views
1

我有以下方法異常不拋出一個異步任務配置

public async Task<bool> Connect() 
    { 
     lock (_connectingLock) 
     { 
      if (_connecting) 
       throw new IOException("Already connecting"); 
      _connecting = true; 
     } 

     try { 
      await tcpClient.ConnectAsync(...); 
     }   
     catch (SocketException e) 
     { 
      return false; 
     } 
     finally 
     { 
      lock (_connectingLock) 
      { 
       _connecting = false; 
      } 
     } 
    } 

現在,我會希望Connect()連續調用拋出IOException,但它不會發生!

可能是什麼原因?

回答

7

致電Connect()不能直接拋出異常。異步方法不要拋出異常。相反,他們會返回任務,等待時,將拋出IOException。 (即任務故障)

如果這不是你想要的,你應該分開電話:

public Task<bool> Connect() 
{ 
    // Eager validation of state... 
    lock (_connectingLock) 
    { 
     if (_connecting) 
      throw new IOException("Already connecting"); 
     _connecting = true; 
    } 
    return ConnectImpl(); 
} 

private async Task<bool> ConnectImpl() 
{ 
    try { 
     await tcpClient.ConnectAsync(...); 
    }   
    catch (SocketException e) 
    { 
     return false; 
    } 
    finally 
    { 
     lock (_connectingLock) 
     { 
      _connecting = false; 
     } 
    } 
} 

目前尚不清楚這是否是在這種情況下,適當不過。通常很好地拋出像ArgumentException這樣的東西,但如果錯誤並不代表調用代碼本身的錯誤,我認爲返回錯誤的任務反而沒有問題。

+0

看哪! NCrunch變綠了。乾杯! – kasperhj 2013-04-04 17:14:22

+0

這種情況也很簡單,您可以使用'ContinueWith'而不是'await'來實現它,以便異常需要明確包裝到結果任務中,而不是隱式地發生。 – Servy 2013-04-04 17:26:33