views:

62

answers:

2

I'm writing a synchronous method that calls an asynchronous method on another server. The server's method calls a callback when it's done, and in case of error one of the callback's arguments contains an exception. I'd like to throw an exception from my method, with the server's exception as its InnerException. However, in order to capture the exception, I have to box it up, and it seems like there should be an easier way. Is this a code smell? What should I be doing more simply?

My code works like this:

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...
    }
}
+1  A: 

You are making it kinda hard on yourself by putting the lambda in its own method. It gets to be a lot easier if you write it inline. Something like this:

        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);
        }
Hans Passant
true, but then you can't use Edit and Continue.
Simon
+2  A: 

There's nothing intrinsically wrong with passing back a boxed exception from an external process, particularly if you have nested inner exceptions or need the stack trace. If you're only interested in the exception messages, you could simply things by concatenating them into a string and only pass that back.

ebpower