【问题标题】:How to differ from writing exception to a reading one?如何区分写入异常和阅读异常?
【发布时间】:2019-09-30 18:19:24
【问题描述】:

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

当我在另一端离线时使用套接字读取/写入时,我得到相同的异常: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 块?
  • 我可以,但这看起来不太好。我只是想进一步了解,我没有说没有它我就不会相处..
  • 一个问题是您是否需要知道是哪一个引发了异常。你会做一些不同的事情吗?如果您确实需要区分两者,那么单独的尝试/捕获是要走的路。此外,您可以一次尝试多次捕获,而不是 if。首先捕获IoException,然后如果您需要捕获更一般的异常,请捕获Exception。通常我们需要的比我们想象的要少。有时我们在方法中不需要任何 try/catch,外部方法中的异常处理就足够了。

标签: c# sockets exception ioexception


【解决方案1】:

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

如果你只坚持一个 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
    }
}

【讨论】:

  • 更正:您没有将ex.Message.IndexOf(...) 的结果与值进行比较。
  • 美丽。非常感谢。请再做一件事-如果读取功能超过给定的接收超时,为什么我不能引发 TimeOut 异常?
  • 另外,我想了解一下ex.Message.IndexOf(...)-1 的比较。
  • IndexOf 与-1 进行比较基本上是在说“主题字符串不包含指定的子字符串”。您也可以使用!ex.Message.Contains(...),它更现代、更易读。
  • @DanielReyhanian String.IndexOf returns -1 如果没有找到匹配项。
【解决方案2】:

并不是说我赞同这些解决方案中的任何一个,但答案就是答案:你可以选择

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

这些都不像包装每个方法调用那样简单。实际上,包装每个电话都传达了您的意图。在您第一次调用的catch 中,您可以返回/中断/跳过读取调用,这会明确告诉读者您正在快速退出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-30
    • 2023-04-09
    • 1970-01-01
    • 2012-02-21
    • 2018-04-15
    • 2013-12-17
    • 2012-02-11
    • 2012-09-14
    相关资源
    最近更新 更多