Как отличить письменное исключение от читающего? - PullRequest
0 голосов
/ 13 мая 2019

У меня есть сокет, и я хотел бы отправлять сообщения и читать из него.

Когда я читаю / пишу с сокетом, когда другая сторона находится в автономном режиме, я получаю то же исключение: 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?
        }
}

Ответы [ 2 ]

1 голос
/ 13 мая 2019

Не то чтобы я одобрил какое-либо из этих решений, но ответ - это ответ: вы можете либо

  • проанализировать трассировку стека исключения, чтобы выяснить, какой вызов не удался (например, имя методав верхней части фрейма стека
  • установите флаг после записи и выполните логику, основанную на этом флаге

. Все это не так просто, как перенос каждого вызова метода.Фактически, завершение каждого вызова передает ваше намерение. В catch вашего первого вызова вы можете вернуть / прервать / пропустить вызов read, который явно сообщает читателю, что вы быстро спасаетесь.

1 голос
/ 13 мая 2019

Да, обработка исключений требует значительных ресурсов, но иногда это не так уж и плохо.

Если вы придерживаетесь только одной попытки, вы можете проверить сообщение об ошибке.

Примечание: Iтакже добавили вторую попытку триггера для общих (не IO) ошибок

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
    }
}
...