Большая часть кода, который я написал в.NET для совершения вызовов REST, была синхронна. Так как Silverlight на Windows Phone только поддерживает Асинхронные вызовы WebClient и HttpWebRequest, я задавался вопросом, что хороший асинхронный шаблон для Класса, который выставляет методы, которые выполняют вызовы REST.
Например, у меня есть приложение, которое должно сделать следующее.
мой класс выставляет несколько методов:
так как каждый метод должен назвать WebClient с помощью Асинхронных вызовов, что я должен сделать, по существу Вход в систему вызова блока, пока он не возвращается так, чтобы я мог назвать GetAlbums ().
Что хороший путь состоит в том, чтобы пойти об этом в моем классе, который выставляет те методы?
Это действительно зависит от того, что вы хотите делать с этой информацией. Если, например, вы пытаетесь отобразить список альбомов / категорий и т. Д., Один из способов смоделировать это будет
Существует очевидная проблема со случаями, когда вы хотите подождать и не продолжать, пока не получите что-то обратно по сети (например, если вы хотите сохранить страницу входа в систему до тех пор, пока не узнаете, что вы успешно прошли аутентификацию). В этом случае вы можете просто изменить страницу в асинхронном обратном вызове.
Очевидно, вы также можете сделать что-нибудь более интересное и заставить поток ждать события, установленного функцией обратного вызова async. Я рекомендую не делать этого в потоке пользовательского интерфейса, поскольку он ограничивает вашу возможность иметь такие вещи, как тайм-ауты, и, как правило, очень беспорядок.
Вы можете взглянуть на расширения фреймворка Reactive (Rx):
http://www.leading-edge-dev.de/?p=501
http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html
[edit: ooh - нашел хорошую ссылку:] http://rxwiki.wikidot.com/101samples
Они обеспечивают способ "последовательности" событий, действуя только при выполнении определенных условий - например, допустим, у вас есть метод "AuthenticationResult Authenticate(string user, string pass)"
Вы можете сделать что-то вроде:
var foo = Observable.FromAsyncPattern<string, string, AuthenticationResult>
(client.BeginAuthenticate, client.EndAuthenticate);
var bar = foo("username","password");
var result = bar.First();
Эффективно превращая асинхронный метод в синхронный. Вы можете расширить это, чтобы включить "цепочку":
var bar = foo("username", "password")
.Then(authresult => DoSomethingWithResult(authresult));
Отличная штука. :)
Мы написали наш уровень службы на стороне клиента со всеми сигнатурами асинхронных функций, которые выглядят следующим образом:
public void MyFunction(
ArtType arg,
Action<ReturnType> success,
Action<FailureType> failure);
Код службы выполняет асинхронный вызов веб-службы , и когда это возвращает, он вызывает обратный вызов успеха, если вызов был успешным, и обратный вызов сбоя, если произошла ошибка / исключение. Тогда вызывающий код выглядит примерно так:
MyServiceInstance.MyFunction(
blahVar,
returnVal => UIInvoker.Invoke(() =>
{
//some success code here
}),
fault => UIInvoker.Invoke(() =>
{
//some fault handling code here
}));
(UIInvoker - это просто утилита, которая отправляет обратно в пользовательский интерфейс из фонового потока.)