2010-07-24 77 views
3

當使用異步代碼使用BeginXXX/EndXXX模式從流等中讀取數據時,我相信在進行對EndXXX的調用時,會在進程期間發生任何異常。在C#中使用BeginRead捕獲異常

這是否意味着BeginXXX的初始調用永遠不會拋出異常,它總是會被EndXXX拋出?

或者換句話說,我應該用try {} catch {}包含BeginRead嗎?

public StartReading() 
{ 
     // Should this be enclosed with try{}catch{} ? 
     stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(readCallback), stream); 
} 

private void readCallback(IAsyncResult result) 
{ 
    Stream stream = (Stream)result.AsyncState; 

    try 
    { 
     int len = stream.EndRead(result); 

     // Do work... 

    } 
    catch(Exception ex) 
    { 
     // Error handling stuff. 
    } 
} 

回答

2

好,任何代碼可以拋出異常,所以「從不」強...例如,OutOfMemoryExceptionThreadAbortException,或其他一些異常,說明資源飽和度(例如,它在某種程度上可以不會啓動異步操作)。

可能(雖然我沒有測試)也拋出立即如果這是一個只寫流。如果stream原來是null肯定會立即丟掉。

但是!在我提到的所有情況中,正確的行爲可能會讓它冒泡;它們都表明與當前邏輯無關的非常基本的問題。所以不:我不會try/catch在這裏,除非有什麼特定我預料,並想以某種方式處理。

+0

我認爲'從不'會產生一個觀點:)發佈的代碼只是一個框架來解釋我的問題,所以,假設我對傳遞給BeginXXX的參數進行了適當的檢查,任何異常都不會針對該調用本身,而是作爲一個整體的應用程序? – Andy 2010-07-24 09:13:11

+0

@Andy - 有關*讀取數據*的異常應該從'EndXXX'出來。 「Braindead例外」(見Eric Lippert的博客)或病態過程例外可以來自任何地方。 – 2010-07-24 09:22:58

+0

謝謝。僅爲'Braindead例外'參考+1! – Andy 2010-07-24 09:42:36

1

的簡單證明:

public StartReading() 
{  
    // Should this be enclosed with try{}catch{} ? 
    buffer = null; // now it will throw 
    stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(readCallback), stream); 
} 

所以是的,你應該預見例外這裏。

+0

感謝您的回答。請看我對Marc的評論。 – Andy 2010-07-24 09:14:01

+0

@安迪是的,我同意大多數情況都是無關緊要的。在這裏需要擔心的是Stream。如果它不是null但是無效,那麼BeginRead或EndRead中會發生異常嗎? (我不知道)。 – 2010-07-24 09:53:28