web-dev-qa-db-ja.com

スレッドの終了またはアプリケーションの要求により、I / O操作が中止されました

私のアプリケーションは、銀行サーバーのクライアントアプリケーションとして機能しています。アプリケーションは要求を送信し、銀行から応答を取得しています。このアプリケーションは通常は正常に動作していますが、時々

スレッドの終了またはアプリケーションの要求により、I/O操作が中止されました

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);                    

    }
}

同じエラーが表示され始めた後、すべてのトランザクションでこのエラーが発生し始めたら、この問題を解決するために私を助けてください。可能であれば、いくつかのサンプルコードを使用して

よろしく、Ashish Khandelwal

17
funsukvangdu

995は IO完了ポート によって報告されるエラーです。エラーは、ソケットが閉じられている可能性が高いときにソケットからの読み取りを続行しようとしたために発生します。

EndRecieveから0バイトを受け取ると、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);
    }
}

3つのcatchブロックを使用する理由は、中央のブロックのロジックが他の2つのブロックと異なるためです。 BeginReceive/EndReceiveからの例外は通常、ソケットの切断を示しますが、ロジックからの例外によってソケットの受信が停止することはありません。

17
jgauffin

RS232通信でも同じ問題がありました。その理由は、プログラムがcomport(または遅いシリアル通信)よりもはるかに速く実行されるためです。

それを修正するには、_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になります。

6
user4624881

私はこの問題を抱えていました。ソケットが開いていて、開いてから短時間でデータが届かなかったのが原因だと思います。 Devicemasterと呼ばれるシリアルからイーサネットのボックスを読んでいました。 Devicemasterのポート設定を「常時接続」から「データ接続」に変更したところ、問題は解消しました。私はハンスパッサントを非常に尊敬していますが、これがコードを精査することで簡単に解決できるエラーコードであることには同意しません。

0
William Howell

私の場合、リクエストはタイムアウトになりました。ですから、HttpClientの作成中にタイムアウトを増やすだけです。

HttpClient client = new HttpClient();

client.Timeout = TimeSpan.FromMinutes(5);

0
Abhishek kumar

それが起こったときに私がすることはDisableDevice ManagerおよびEnableへのCOMポートです。

それは別のプログラムまたはスレッドとの通信を停止し、あなたのために自由になります。

これがうまくいくことを願っています。よろしく。

0
JD - DC TECH