2010-07-24 114 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