Шаблоны проектирования асинхронных веб-сервисов

При написании приложения Silverlight, подключенного к веб-службе WCF, единственная возможность, которую мы представляем при использовании веб-службы, - это выполнять асинхронные вызовы интерфейса WS.

т.е.

WebService client = new WebService();
client.ServiceMethodCompleted += new EventHandler<Args>(client_Handler);
client.ServiceMethodAsync();
client.close()

...followed by
void client_Handler(object sender, Args e)
{
    //Next step, possibly another method?
}

Хотя я понимаю причину асинхронных вызовов при написании веб-приложений (сеть безопасности), какой тип шаблона дизайна можно использовать, если бы был написан метод, в котором каждый шаг зависел от результата вызова веб-службы?

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

public MyPage() //Constructor
{
    CheckCredentialsAsync();

    if(result.IsUserTypeA)
    {
       //something complex
    }
    else if(result.IsUserTypeB)
    {
       //something else complex
    }
    ...etc

}

Есть ли способ сделать это без использования метода "домино", вызванного предыдущим событием завершения асинхронных вызовов? Кажется, что это может стать грязным, если есть много взаимодействия клиент / сервис.

Спасибо!

3 ответа

Решение

Лучшее моделирование, которое я знаю для таких шаблонов, - это конечный автомат, управляемый событиями. Завершение асинхронных методов - это события, а ваши "сложные операции" - действия, ваш экземпляр MyPage находится в текущем состоянии. Однако FSM может быть довольно проблематичным для любого значительного числа состояний и событий, и хотя их можно каким-то образом контролировать, составляя более простые FSM, я бы не стал называть этот шаблон интуитивно понятным и легким с любой точки зрения.

Честно говоря, я часто предпочитаю цепочку обратных вызовов, которые вы описываете. Эффект "домино" не обязательно плох, когда вы напишете пару таких модулей, вы получите его. Его сложность в основном определяется количеством возможных ветвей выполнения в "сложных объектах". Где в синхронном пути у вас будет ветвь if, в асинхронном пути вы, скорее всего, будете иметь два отдельных обратных вызова. Больше кода для ввода, но не обязательно сложнее для понимания. И часть "больше кода" может быть позаботилась о правильной фабрике коэффициентов в помощников.

Я считаю, что я не работал с классами Silverlight, мой опыт в основном связан с асинхронным поведением операций WebRequest, SqlClient и Stream. В конце концов, самой сложной частью я считаю разделение обработки ошибок и разделение владения ресурсами, поскольку using шаблон гораздо менее полезен с асинхронным.

Если вы не хотите связывать обратные вызовы вместе, проверьте AsyncEnumerator Джеффри Рихтера: http://www.wintellect.com/PowerThreading.aspx

Он также поддерживает Silverlight.

Я С ТОБОЙ СОГЛАСЕН:
Глядя на длинную цепочку звонков в домино, уродливо. Это сбивает с толку код, потому что (бесконечный) список вызовов и обратных вызовов на вашей странице не обязательно сообщает другим разработчикам, что данная серия является частью какого-то одного набора. Вот почему я бы обернул эти вызовы в один объект, используя шаблон проектирования.

Если ваша домино-цепочка звонков...

Использует данные предыдущих звонков:
Я бы обернул эти вызовы в объект, используя шаблон DECORATOR deign. Хорошим примером того, что использует шаблон декоратора, является объект STREAM.

Если ваша домино-цепочка звонков...

НЕ ИСПОЛЬЗУЕТ ПРЕДЫДУЩИЕ ЗВОНКИ:
Я бы обернул эти вызовы в объект, используя схему сообразительности CHAIN ​​OF ОТВЕТСТВЕННОСТИ.

ТЕМ НЕ МЕНИЕ
Есть много причин, по которым вы можете использовать или не использовать один или другой. Я просто пытаюсь удовлетворить вашу конкретную ситуацию. Вот как вы решаете, какой из них использовать.

Другие вопросы по тегам