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

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

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

ошибка с кодом ошибки, поскольку 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);                    

    }
}

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

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

8 ответов

Решение

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

Получение 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 обычно указывают на отключение сокета, в то время как исключения из вашей логики не должны останавливать получение сокета.

В моем случае время ожидания запроса истекло. Итак, все, что вам нужно сделать, это увеличить время ожидания при создании HttpClient.

Клиент HttpClient = новый HttpClient();

client.Timeout = TimeSpan.FromMinutes(5);

У меня была такая же проблема со связью 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,

В моем случае проблема была вызвана тем, что, начиная с .NET 5 или 6, вы должны либо вызывать асинхронные методы для асинхронного потока, либо методы синхронизации для синхронизирующего потока. Так что если я позвоню FlushAsync Я должен получить контекст, используя GetContextAsync

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

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

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

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

Я столкнулся с этой ошибкой при использовании Entity Framework Core с сервером Azure Sql, работающим в режиме отладки в Visual Studio. Я понял, что это исключение, но не проблема. EF написан для корректной обработки этого исключения и завершения работы. У меня был настроен VS на прерывание всех исключений, так оно и было. Как только я снял флажок в VS, чтобы не прерывать это исключение, мой код C#, вызывающий EF, используя Azure Sql, работал каждый раз.

Ах да. Ошибка 995 == 0x3E3. Я только что наткнулся на это, работая с последовательной связью и получая данные с ошибкой четности. есть атрибут , связанный с этим поведением:

DCB::fAbortOnError == [TRUE | ЛОЖЬ]

Если настроено как TRUE и в принимаемых данных возникает ошибка четности,

драйвер завершает все операции чтения и записи со статусом ошибки. Драйвер не будет принимать никаких дальнейших операций связи, пока приложение не подтвердит ошибку, вызвав функцию ClearCommError .

Это цитата из документации Microsoft по В структуре DCBDCB . Прерывание может произойти и при других ошибках, кроме четности... ни одной из которых я до сих пор не испытал.

Другие вопросы по тегам