2010-06-16 18 views
8

Rozważmy następujący kod:Gdzie mam obsługiwać asynchroniczne wyjątki?

class Foo { 
    // boring parts omitted 

    private TcpClient socket; 

    public void Connect(){ 
     socket.BeginConnect(Host, Port, new AsyncCallback(cbConnect), quux); 
    } 

    private void cbConnect(IAsyncResult result){ 
      // blah 
    } 
} 

Jeśli socket zgłasza wyjątek po BeginConnect zwrotów i przed cbConnect jest wywoływana, gdzie to pop-up? Czy wolno nawet rzucać się w tło?

Odpowiedz

7

Przykładowa procedura kodowania wyjątków dla delegata asynch z msdn forum. Wierzę, że dla TcpClient wzór będzie taki sam.

using System; 
using System.Runtime.Remoting.Messaging; 

class Program { 
    static void Main(string[] args) { 
    new Program().Run(); 
    Console.ReadLine(); 
    } 
    void Run() { 
    Action example = new Action(threaded); 
    IAsyncResult ia = example.BeginInvoke(new AsyncCallback(completed), null); 
    // Option #1: 
    /* 
    ia.AsyncWaitHandle.WaitOne(); 
    try { 
     example.EndInvoke(ia); 
    } 
    catch (Exception ex) { 
     Console.WriteLine(ex.Message); 
    } 
    */ 
    } 

    void threaded() { 
    throw new ApplicationException("Kaboom"); 
    } 

    void completed(IAsyncResult ar) { 
    // Option #2: 
    Action example = (ar as AsyncResult).AsyncDelegate as Action; 
    try { 
     example.EndInvoke(ar); 
    } 
    catch (Exception ex) { 
     Console.WriteLine(ex.Message); 
    } 
    } 
} 
+0

Należy pamiętać, że opcja nr 1 zablokuje wątek do momentu zakończenia czynności. Równie dobrze można wywołać metodę synchronicznie. Opcja 2 jest sposobem, aby przejść tutaj ... – Marc

3

Jeśli proces akceptowania połączenia spowoduje błąd, zostanie wywołana metoda cbConnect. Aby zakończyć połączenie, choć trzeba zrobić następujące wywołanie

socket.EndConnection(result); 

W tym momencie błąd w procesie BeginConnect będzie przejawiało w rzucony wyjątek.

Powiązane problemy