Операция ввода-вывода была прервана из-за выхода из потока или запроса приложения - PullRequest
10 голосов
/ 29 августа 2011

Мое приложение работает как клиентское приложение для сервера Банка. Заявка отправляет запрос и получает ответ от банка. Это приложение нормально работает нормально, но иногда

Операция ввода-вывода была прервана из-за выхода из потока или запрос заявки

ошибка с кодом ошибки 995.

public void OnDataReceived(IAsyncResult asyn)
{
    BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", 
                                        ref swReceivedLogWriter, strLogPath, 0);
    try
    {
        SocketPacket theSockId = (SocketPacket)asyn.AsyncState;

        int iRx = theSockId.thisSocket.EndReceive(asyn); //Here error is coming
        string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);                    

    }
}

Как только эта ошибка начинает появляться для всех транзакций, после того как эта ошибка начинает появляться, так пожалуйста, помогите мне разобраться с этой проблемой. Если возможно, то с некоторым примером кода

С уважением, Ашиш Хандельвал

Ответы [ 4 ]

13 голосов
/ 30 августа 2011

995 - ошибка, сообщаемая IO Completion Port .Ошибка возникает, когда вы пытаетесь продолжить чтение из сокета, когда он, скорее всего, был закрыт.

Получение 0 байтов из EndRecieve означает, что сокет был закрыт, как и большинство исключений, из-за которых EndRecieveбросить.

Вам нужно начать разбираться с этими ситуациями.

Никогда не игнорируйте исключения, они выбрасываются по причине.

Обновление

Тамничего не говорит о том, что сервер делает что-то не так.Соединение может быть потеряно по многим причинам, таким как незанятое соединение, закрываемое коммутатором / маршрутизатором / брандмауэром, ненадежная сеть, плохие кабели и т. Д.

Я хочу сказать, что вы ДОЛЖНЫ обрабатывать отключения.Правильный способ сделать это состоит в том, чтобы избавиться от сокета и попытаться подключить новый через определенные интервалы.

Что касается обратного вызова приема, то более правильный способ его обработки - что-то вроде этого (полупсевдокод):

public void OnDataReceived(IAsyncResult asyn)
{
    BLCommonFunctions.WriteLogger(0, "In :- OnDataReceived", ref swReceivedLogWriter, strLogPath, 0);

    try
    {
        SocketPacket client = (SocketPacket)asyn.AsyncState;

        int bytesReceived = client.thisSocket.EndReceive(asyn); //Here error is coming
        if (bytesReceived == 0)
        {
          HandleDisconnect(client);
          return;
        }
    }
    catch (Exception err)
    {
       HandleDisconnect(client);
    }

    try
    {
        string strHEX = BLCommonFunctions.ByteArrToHex(theSockId.dataBuffer);                    

        //do your handling here
    }
    catch (Exception err)
    {
        // Your logic threw an exception. handle it accordinhly
    }

    try
    {
       client.thisSocket.BeginRecieve(.. all parameters ..);
    }
    catch (Exception err)
    {
       HandleDisconnect(client);
    }
}

причина, по которой я использую три блока catch, заключается просто в том, что логика для среднего блока отличается от двух других.Исключения из BeginReceive / EndReceive обычно указывают на отключение сокета, в то время как исключения из вашей логики не должны останавливать получение сокета.

5 голосов
/ 02 марта 2015

У меня была такая же проблема со связью RS232.Причина в том, что ваша программа выполняется намного быстрее, чем компорт (или медленная последовательная связь).

Чтобы исправить это, мне пришлось проверить, если IAsyncResult.IsCompleted==true.Если не завершено, то IAsyncResult.AsyncWaitHandle.WaitOne()

Примерно так:

Stream s = this.GetStream();
IAsyncResult ar = s.BeginWrite(data, 0, data.Length, SendAsync, state);
if (!ar.IsCompleted)
    ar.AsyncWaitHandle.WaitOne();

В большинстве случаев ar.IsCompleted будет true.

0 голосов
/ 13 октября 2016

У меня была эта проблема.Я думаю, что это было вызвано открытием сокета и отсутствием данных, поступающих в течение короткого времени после открытия.Я читал из последовательного в локальную сеть, которая называется Devicemaster.Я изменил настройку порта Devicemaster с «всегда подключаться» на «подключаться к данным», и проблема исчезла.Я очень уважаю Ханса Пассанта, но я не согласен с тем, что это код ошибки, который можно легко исправить, изучив код.

0 голосов
/ 03 декабря 2015

Что я делаю, когда это происходит, Отключаю COM-порт в Диспетчер устройств и Включаю снова.

Это останавливаетсвязь с другой программой или потоком и стать бесплатным для вас.

Я надеюсь, что это работает для вас.Привет.

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