写异常与读异常有何不同?

How to differ from writing exception to a reading one?

我有一个套接字,我想发送消息并从中读取消息。

当我 read/write 使用套接字而另一端处于离线状态时,我得到相同的异常:System.IO.IOException: Unable to read data from the transport connection: Operation on non-blocking socket would block

除了有两个单独的 try-catch 块之外,我如何确定它发生在两个中的哪一个?读超时时间结束就不能得到一个Timeout Exception吗?

示例:

try
{
    SendData("!GetLocation!");
    string data = GetData();
}
catch (Exception ex)
{
    if (ex is System.IO.IOException)
        {
            //How can I identify if the exception was raised at the read method or the write method?
        }
}

是的,异常处理需要大量资源,但有时还不错。

如果你只坚持一个 try-catch 你可以查看错误信息。

注意:我还为一般(非 IO)错误添加了第二个 try-catch

try
{
    SendData("!GetLocation!");
    string data = GetData();
}
catch (System.IO.IOException ex)
{
    if (ex.Message.IndexOf("Unable to read") != -1)
    {
     // GetData error
    }
    else if (ex.Message.IndexOf("Unable to write") != -1)
    {
     // SendData error
    }
    else
    {
       //Other IO errors
    }

}
catch(Exception exc)
{
    // Unspected errors
}

您还可以设置一个布尔变量并检查它的值以了解它在哪里 破坏了你的代码。

bool sendCalled = false;

try
{
    SendData("!GetLocation!");
    sendCalled = true;
    string data = GetData();
}
catch (System.IO.IOException ex)
{
    if (sendCalled)
    {
     // GetData error
    }
    else
    {
     // SendData error
    }
}

并不是说我认可这两种解决方案中的任何一种,但答案就是答案:您可以

  • 分析异常的堆栈跟踪以找出哪个调用失败(例如堆栈帧顶部的方法名称
  • 写入后设置一个标志,并根据该标志执行逻辑

这些都不像包装每个方法调用那样直接。事实上,包装每个电话传达你的意图。在您的第一个调用的 catch 中,您可以 return/break/skip 读取调用,它明确告诉 reader 您正在快速退出。