开发者

Want event handler to run only once/ Designing state machine?

I have a web service with two methods:

RetrieveFirstLevelOptions() and RetrieveSecondLevelOptions(int levelOneOption).

The GUI contains two comboBoxes: FirstLevelOptionsCombo and SecondLevelOptionsCombo.

I am having trouble with creating a control flow for the initialization stage when I have to make a request to RetrieveFirstLevelOptions() and then, once the results are in, call RetrieveSecondLevelOptions(default levelOneOption = 0).

The problem is that since everything happens asynchronously I don't know what the best approach is to allow this behaviour tak开发者_高级运维e place once and only once, at the beginning.

An option I would love to have is to attach a second event handler to the RetieveFirstLevelOptionsCompleted event and have it remove itself after running only once. But it looks like such a behaviour is impossible to get.

Another option would be to have a boolean flag to indicate whether in Initialization phase and if it is, then the handler for RetrieveFirstLevelOptionsCompleted would execute some additional logic. However this idea makes it look like all event handlers would have to check for state information and do different things depending on the current state. This seems to be bad design because the control flow seems to be descentralized.

I want to have a centralized control flow mechanism that will make the decisions in one spot. But how can this be done when everything is executed asynchronously?


"An option I would love to have is to attach a second event handler to the RetieveFirstLevelOptionsCompleted event and have it remove itself after running only once. But it looks like such a behaviour is impossible to get."

Is there some reason this isn't working:

class Example
{
    SomeWebService myService;

    Example()
    {
        // do stuff
        myService.RetrieveFirstLevelOptionsCompleted += MyHandlerMethod;
    }

    void MyHandlerMethod(object sender, RetrieveFirstLevelOptionsCompletedEventArgs e)
    {
        // do stuff
        myService.RetrieveFirstLevelOptionsCompleted -= MyHandlerMethod;
        // potentially attach next event handler for all subsequent calls
        myService.RetrieveFirstLevelOptionsCompleted += MyHandlerMethod2;
    }
}


The pattern that I usually use in a situation like this is to create a wrapper around the Async web service proxy method that accepts a callback method. The callback method then gets passed to the RetrieveFirstLevelOptionsAsync() method like so:

public void RetrieveFirstLevelOptions(Action callback)
{
    client.RetrieveFirstLevelOptionsAsync(callback);
}

void client_RetrieveFirstLevelOptionsCompleted(object sender, AsyncCompletedEventArgs e)
{
    var callback = e.UserState as Action;
    if (callback != null)
    {
        callback();
    }
}

So when you call RetrieveFirstLevelOptions(), you just pass the callback that you want to run only once, and you don't ever have to worry about it getting called multiple times. Presumably you'd put your call to RetrieveSecondLevelOptions() within that callback.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜