views:

38

answers:

1

I'm fairly new on a project and ran across an interesting design paradigm for some asynchronous calls we make to the database (variables and function name altered):

private void OnLogin(object selectedInitialState,
                     AsyncEventCompletedCallback<EmptyAsyncEventArgs> userCallback,
                     object userState)

Example usages:

OnLogin(
    null,
    args =>
    {
        if (args.IsSuccess)
            DetermineNextStep(); //When done, continue to this step
        else
            //NOTE: This probably means we couldn't connect to the DB
            // Handle this case
    },
    null);

OnLogin(
    newInitialState,
    args =>
    {
         ReLoginUser(); //Was logged in; re-logging in user with different initial state
    },
    null);

The example usages show two different calls to this function for two different cases - an initial login and a re-login (not technically a re-login, but a restart of the application for the currently logged in user with a different initial state).

What bothers me is that the callback function in these two cases is different. I'm used to seeing a function take a callback to allow users of the function to provide custom implementations within the purview of the function being called.

In the above case, though, the callback function changes the control flow. Depending on which callback function is provided, the subsequent calling functions after the async call returns are different. Is this a code smell or just an inventive use for callbacks?

+1  A: 

I'm interpreting the OnLogin function as starting an operation that will invoke the callback exactly once upon completion.

In this case, the code is actually quite normal. This is not uncommon when writing a program asynchronously. Considering that the alternative is keeping a "state" with a (small) state machine in the callback function, I think different callbacks is actually the more elegant solution. It handles the asynchronous "state" implicitly instead of explicitly.

Stephen Cleary