2010-02-16 20 views
0

J'écris une méthode synchrone qui appelle une méthode asynchrone sur un autre serveur. La méthode du serveur appelle un rappel quand c'est fait, et en cas d'erreur un des arguments du callback contient une exception. Je voudrais lancer une exception de ma méthode, avec l'exception du serveur comme InnerException. Cependant, pour capturer l'exception, je dois l'encadrer, et il semble qu'il devrait y avoir un moyen plus facile. Est-ce une odeur de code? Que devrais-je faire plus simplement?Comment dois-je gérer les exceptions qui sont levées pendant les méthodes asynchrones que j'ai rendues synchrones? (ou, Est-ce une odeur de code?)

Mon code fonctionne comme ceci:

private class BoxedException 
{ 
    public Exception Exception; 
} 

public bool MyMethod() 
{ 
    EventWaitHandle waitHandle = new new EventWaitHandle(false, EventResetMode.ManualReset); 
    BoxedException boxedException = new BoxedException(); 

    bool called = theServer.ServerMethod(getCallback(waitHandle, boxedException)); 
    if (called) 
    { 
     waitHandle.WaitOne(); 

     if (boxedException.Exception != null) 
      throw new Exception("ServerMethod failed", boxedException.Exception); 
    } 
} 

private ServerCallback getCallback(EventWaitHandle waitHandle, BoxedException be) 
{ 
    return (object sender, ServerArgs e) => 
    { 
     handleServerArgs(e, be); 
     waitHandle.Set(); 
    }; 
} 

private void handleServerArgs(ServerArgs e, BoxedException be) 
{ 
    if (e.Exception != null) 
    { 
     be.Exception = e.Exception; 
    } 
    else 
    { 
     // do stuff... 
    } 
} 

Répondre

2

Il n'y a rien d'intrinsèquement mauvais avec repassant une exception en boîte d'un processus externe, en particulier si vous avez des exceptions imbriquées internes ou besoin de la trace de la pile. Si vous êtes seulement intéressé par les messages d'exception, vous pourriez simplement les choses en les concaténant dans une chaîne et ne les transmettre que par retour.

1

Vous faites ça un peu dur sur vous-même en mettant le lambda dans sa propre méthode. Cela devient beaucoup plus facile si vous l'écrivez en ligne. Quelque chose comme ceci:

 var waitHandle = new ManualResetEvent(false); 
     Exception fault = null; 
     bool called = theServer.ServerMethod((obj, se) => { 
      if (se.Exception != null) fault = se.Exception; 
      else ProcessServerResponse(se); 
      waitHandle.Set(); 
     }); 
     if (called) { 
      waitHandle.WaitOne(); 
      if (fault != null) kaboom(fault); 
     } 
+0

true, mais vous ne pouvez pas utiliser Modifier et continuer. – Simon