Хотите, чтобы обработчик событий запускался только один раз / Проектирование конечного автомата? - PullRequest
0 голосов
/ 16 февраля 2010

У меня есть веб-сервис двумя способами:

RetrieveFirstLevelOptions () и RetrieveSecondLevelOptions (int levelOneOption).

Графический интерфейс содержит два комбинированных списка: FirstLevelOptionsCombo и SecondLevelOptionsCombo.

У меня проблемы с созданием потока управления для этапа инициализации, когда мне нужно сделать запрос к RetrieveFirstLevelOptions (), а затем, когда результаты получены, вызвать RetrieveSecondLevelOptions (по умолчанию levelOneOption = 0).

Проблема в том, что, поскольку все происходит асинхронно, я не знаю, каков наилучший подход, чтобы это поведение происходило один раз и только один раз в начале.

Вариант, который мне хотелось бы иметь, - это присоединить второй обработчик события к событию RetieveFirstLevelOptionsCompleted и заставить его удалить себя после запуска только один раз. Но похоже, что такое поведение невозможно получить.

Другим вариантом может быть наличие логического флага для указания того, находится ли на этапе инициализации, и если это так, то обработчик для RetrieveFirstLevelOptionsCompleted будет выполнять некоторую дополнительную логику. Однако из-за этой идеи все обработчики событий должны будут проверять информацию о состоянии и делать разные вещи в зависимости от текущего состояния. Это кажется плохим дизайном, потому что поток управления кажется децентрализованным.

Я хочу иметь механизм централизованного управления потоком, который будет принимать решения в одном месте. Но как это сделать, когда все выполняется асинхронно?

Ответы [ 2 ]

1 голос
/ 16 февраля 2010

"Один вариант, который я хотел бы иметь, это присоединить второй обработчик события к событию RetieveFirstLevelOptionsCompleted и заставить его удалить себя после запуска только один раз. Но похоже, что такое поведение невозможно получить."

Есть ли какая-то причина, по которой это не работает:

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;
    }
}
1 голос
/ 16 февраля 2010

Шаблон, который я обычно использую в такой ситуации, заключается в создании оболочки вокруг метода прокси-сервера веб-службы Async, который принимает метод обратного вызова. Затем метод обратного вызова передается методу RetrieveFirstLevelOptionsAsync () следующим образом:

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();
    }
}

Поэтому, когда вы вызываете RetrieveFirstLevelOptions (), вы просто передаете обратный вызов, который хотите запустить, только один раз, и вам никогда не придется беспокоиться о том, что он вызывается несколько раз. Предположительно, вы бы поместили свой вызов в RetrieveSecondLevelOptions () внутри этого обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...