2011-08-29 13 views
6

La mia applicazione funziona come applicazione client per il server Bank. L'applicazione sta inviando richiesta e riceve risposta dalla banca. Questa applicazione è normalmente funziona bene, ma a volteL'operazione di I/O è stata interrotta a causa di un'uscita di thread o di una richiesta di applicazione

L'operazione di I/O è stata interrotta a causa di un exit filo o un'applicazione richiesta

dell'errore con codice di errore come 995 sta venendo.

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

    } 
} 

Una volta che questo errore di iniziare a venire per tutte le transazioni dopo che lo stesso errore cominciano ad apparire, in modo prego di aiutarmi a risolvere questo problema. Se possibile poi con alcuni esempi di codice

saluti, Ashish Khandelwal

+0

Ci sono alcuni errori di Windows che sono descrittivi e affidabili come quello. Non possiamo aiutarti a trovare il thread che sta terminando troppo presto. Aggiungi qualche traccia al tuo codice se non riesci a trovarlo. –

risposta

9

995 è un errore riportato dal IO Completion Port. L'errore deriva dal tentativo di continuare a leggere dal socket quando è stato probabilmente chiuso.

La ricezione di 0 byte da EndRecieve indica che il socket è stato chiuso, così come la maggior parte delle eccezioni che verrà generato da EndRecieve.

È necessario iniziare a gestire tali situazioni.

Mai e poi mai ignorare le eccezioni, vengono lanciati per una ragione.

Aggiornamento

Non c'è nulla che dice che il server non fa nulla di male. Una connessione può essere persa per molti motivi poiché la connessione inattiva viene chiusa da switch/router/firewall ecc. Anche gli errori di rete si verificano.

Quello che sto dicendo è che DEVI gestire le disconnessioni. Il modo corretto per farlo è quello di smaltire il socket e provare a collegarne uno nuovo a determinati intervalli.

Per quanto riguarda la ricezione callback un modo più corretto di gestire, è qualcosa di simile (pseudo codice semi):

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 ragione del perché sto usando tre blocchi catch è semplicemente perché la logica per quello centrale è diverso dagli altri due. Le eccezioni da BeginReceive/EndReceive di solito indicano la disconnessione della presa mentre le eccezioni dalla logica non dovrebbero interrompere la ricezione del socket.

+1

Gentile jgauffin, Grazie per la risposta, ma il problema è che solo l'applicazione client proviene dalla nostra azienda e il server proviene da qualche banca, quindi se il socket è chiuso dalla loro parte, allora come esprimere loro che questo problema è dalla loro parte, come possiamo gestiscilo senza eccezioni, ovvero quando lancia un'eccezione in endreceive possiamo scrivere qualsiasi comando che ci dirà che la ricezione dei dati è 0 – funsukvangdu

+1

leggi il mio aggiornamento. – jgauffin

+0

@funsukvangdu: hai altre domande? – jgauffin

4

Ho avuto lo stesso problema con la comunicazione RS232. Il motivo è che il tuo programma viene eseguito molto più velocemente del comportamento (o della comunicazione seriale lenta).

Per risolvere il problema, ho dovuto verificare se il IAsyncResult.IsCompleted==true. Se non completata, quindi IAsyncResult.AsyncWaitHandle.WaitOne()

Ti piace questa:

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

maggior parte del tempo, ar.IsCompleted sarà true.

+0

funziona come una magia! Grazie –

0

Quello che faccio quando succede è Disabilita la porta COM in Gestione periferiche e Attiva di nuovo.

Arresta le comunicazioni con un altro programma o thread e diventa gratuito per te.

Spero che questo funzioni per voi. Saluti.

0

Ho avuto questo problema. Penso che sia stato causato dall'apertura della presa e dall'arrivo di dati in breve tempo dopo l'apertura. Stavo leggendo da una scatola seriale a Ethernet chiamata Devicemaster. Ho cambiato l'impostazione della porta Devicemaster da "Connetti sempre" a "Connetti ai dati" e il problema è scomparso. Ho un grande rispetto per Hans Passant, ma non sono d'accordo sul fatto che si tratti di un codice di errore che puoi facilmente risolvere scrutando il codice.

Problemi correlati