Шаблоны проектирования асинхронных веб-сервисов - PullRequest
0 голосов
/ 27 октября 2009

При написании приложения 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 ]

4 голосов
/ 27 октября 2009

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

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

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

2 голосов
/ 31 октября 2009

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

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

0 голосов
/ 10 февраля 2011

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

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

ИСПОЛЬЗУЕТ ДАННЫЕ ПРЕДЫДУЩИХ ВЫЗОВОВ:
Я бы обернул эти вызовы в объект, используя шаблон DECORATOR . Хорошим примером того, что использует шаблон декоратора, является объект STREAM .

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

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

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

...