2010-02-08 9 views
4

Notre société fournit un composant réseau (DLL) pour une application GUI.Pourquoi cette exception SocketException n'est-elle pas interceptée par une routine de capture générique?

Il utilise une minuterie qui vérifie les déconnexions. Si elle veut se reconnecter, il appelle:

internal void timClock_TimerCallback(object state) 
{ 
    lock (someLock) 
    { 
    // ... 
    try 
    { 
     DoConnect(); 
    } 
    catch (Exception e) 
    { 
     // Log e.Message omitted 
     // Raise event with e as parameter 
     ErrorEvent(this, new ErrorEventArgs(e)); 
     DoDisconnect(); 
    } 
    // ... 
    } 
} 

Le problème est, à l'intérieur de la routine DoConnect() SocketException est jeté (et non pris). Je suppose que le catch (Exception e) devrait attraper TOUTES les exceptions mais de façon ou d'autre le SocketException n'a pas été attrapé et montre à l'application de GUI.

protected void DoConnect() 
{ 
    // 
    client = new TcpClient(); 
    client.NoDelay = true; 
    // In the following call the SocketException is thrown 
    client.Connect(endPoint.Address.ToString(), endPoint.Port); 
    // ... (login stuff) 
} 

Le doc a confirmé que SocketException étend l'exception. Le stacktrace qui est apparu:

TcpClient.Connect() -> DoConnect() -> timClock_TimerCallback 

Ainsi, l'exception n'est pas jeté à l'extérieur du bloc try/catch.

Des idées pour lesquelles cela ne fonctionne pas?

+0

Ce problème se produit uniquement lorsqu'un débogueur est attaché ou toujours lorsque le code est en cours d'exécution? Capture est également garanti pour attraper toutes les exceptions dans le bloc try - mais si votre DoConnect exécute un feu et oublie que les sources de l'exception, DoConnect retournera et le traitement continuera à causer l'exception d'être gérée par votre gestionnaire prévu. – cfeduke

Répondre

0

J'ai écrit un petit programme et j'étais incapable de reproduire, une SocketException a été attrapée dans un TimerCallback.

Alors je vous suggère de repenser votre analyse, le problème peut ne pas être ce que vous pensez qu'il est. Quelques suggestions:

  • exécutez-le en dehors du temporisateur. T | hat prend l'enfilage de la boucle.
  • exécutez-le dans le débogueur. Où l'exception se produit-elle vraiment?
  • étape de la gestion des exceptions. ErrorEvent fait-il ce qu'il devrait faire?
+0

Merci, j'ai posé la question parce que je n'avais pas non plus d'explication pourquoi cela s'est passé et j'espérais une nouvelle inspiration. Je ne pense pas que ce soit reproductible (comme votre programme l'a montré) mais cela s'est évidemment passé, donc j'ai dû enquêter .. – Tarnschaf

+0

Le comportement n'est toujours pas reproductible, j'ai donc ajouté du code de débogage et j'attendrai s'il se reproduit. Accepter votre réponse parce que c'est plus simple. – Tarnschaf

1

Si ErrorEvent déclenche réellement une autre exception (par commentaire), alors DoDisconnect() n'est jamais exécuté.

Sinon, l'exception que vous voyez peut-être à venir sous forme DoDisconnect()

+0

voir la stacktrace ajoutée pourquoi cela ne peut pas être la solution – Tarnschaf

0

Pouvez-vous poster le code DoConnect()?

Aussi des choses à essayer: Pouvez-vous l'attraper dans le DoConnect()? Essayez d'attraper l'exception spécifique au lieu de simplement le générique. Comment réagit-il si vous utilisez le mode débogage?

+0

En lisant les réponses que vous avez laissées aux autres, laissez votre code tel quel mais ajoutez un SECOND block de catch pour attraper soit une SocketException ou une Win32Exception. – Roast

+0

a ajouté la méthode DoConnect() comme demandé. Avez-vous également une explication pour votre idée en tant que SocketException extends Win32Exception extends ExternalException extends Exception? – Tarnschaf

+0

Il y a deux raisons, .NET 1.1 win32exception n'a pas été dérivé de Exception. Sinon, votre exception n'est pas interceptée car elle est lancée sur un thread différent démarré dans DoConnect. – Roast

0

Votre timClock_TimerCallback n'est pas appelé dans le même thread que l'instruction catch veut intercepter une exception. Vous devez intercepter l'exception à l'intérieur de timClock_TimerCallback, puis appeler une méthode qui s'appelle elle-même, puis renvoyer l'exception dans le bon thread.

Pas sûr que cela fonctionne, mais vous pourriez essayer.

+1

Cela semble intéressant .. mais le TcpClient.Connect() est appelé à partir du thread TimerCallback où réside également le catch, quel autre thread pourrait être impliqué? – Tarnschaf

+0

Oups, j'ai pensé que le timClock_TimerCallback était en quelque sorte appelé dans DoConnect, mais c'est évidemment faux. J'ai peur que ma réponse ne t'aide pas. –