web-dev-qa-db-fra.com

L'opération d'E/S a été abandonnée à cause d'une sortie de thread ou d'une demande d'application

Mon application fonctionne en tant qu'application client pour le serveur de banque. L'application envoie une demande et obtient une réponse de la banque. Cette application fonctionne normalement bien, mais parfois 

L'opération d'E/S a été abandonnée à cause d'une sortie de thread ou de Demande d'application

erreur avec code d'erreur car 995 arrive. 

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

    }
}

Une fois que cette erreur commence à se produire pour toutes les transactions, cette erreur commence à apparaître, alors Aidez-moi à résoudre ce problème. Si possible, avec un exemple de code 

Cordialement, Ashish Khandelwal

9
funsukvangdu

995 est une erreur signalée par le IO Port d’achèvement . L'erreur survient lorsque vous essayez de continuer à lire à partir du socket alors qu'il a très probablement été fermé.

Recevoir 0 octet de EndRecieve signifie que le socket a été fermé, de même que la plupart des exceptions que EndRecieve lèvera. 

Vous devez commencer à gérer ces situations. 

Ne jamais ignorer les exceptions, elles sont renvoyées pour une raison.

Mise à jour

Rien ne dit que le serveur fait quelque chose de mal. Une connexion peut être perdue pour de nombreuses raisons, telles qu'une connexion inactive fermée par un commutateur/routeur/pare-feu, un réseau fragile, des câbles défectueux, etc.

Ce que je dis, c'est que vous DEVEZ gérer les déconnexions. Pour ce faire, vous devez disposer de la prise et essayer d’en connecter une nouvelle à certains intervalles.

En ce qui concerne le rappel de réception, une manière plus appropriée de le gérer est quelque chose comme ceci (semi-pseudo-code):

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

la raison pour laquelle j'utilise trois blocs catch est tout simplement parce que la logique de celle du milieu est différente de celle des deux autres. Les exceptions de BeginReceive/EndReceive indiquent généralement la déconnexion du socket, tandis que les exceptions de votre logique ne doivent pas arrêter la réception du socket.

12
jgauffin

J'ai eu le même problème avec la communication RS232. La raison en est que votre programme s'exécute beaucoup plus rapidement que le comport (ou une communication série lente).

Pour résoudre ce problème, je devais vérifier si le IAsyncResult.IsCompleted==true. Si non complété, alors IAsyncResult.AsyncWaitHandle.WaitOne()

Comme ça :

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

La plupart du temps, ar.IsCompleted sera true.

4
user4624881

J'ai eu ce problème. Je pense que cela a été causé par l'ouverture du socket et par l'absence de données arrivant peu de temps après l'ouverture. Je lisais une boîte série vers Ethernet appelée Devicemaster. J'ai changé le paramètre du port de Devicemaster de "connecter toujours" à "se connecter sur des données" et le problème a disparu. J'ai beaucoup de respect pour Hans Passant mais je ne pense pas qu'il s'agisse d'un code d'erreur que vous pouvez facilement résoudre en scrutant le code. 

0
William Howell

Ce que je fais quand cela se produit est Désactiver le port COM dans le Gestionnaire de périphériques et Activer à nouveau.

Il arrête les communications avec un autre programme ou thread et devient gratuit pour vous.

J'espère que cela fonctionne pour vous. Cordialement.

0
JD - DC TECH