Управление вызовами асинхронных служб с использованием Silverlight и Reactive Extensions - PullRequest
5 голосов
/ 21 июля 2011

Так что я читаю на Rx и с трудом справляюсь с этим.У меня есть приложение Silverlight, которое должно сделать, скажем, 6 вызовов определенной службы асинхронно.В старые времена мы справлялись с этим, совершая вызовы и запрашивая токен userState / token, чтобы сопоставить ответ с запросом, поскольку они не гарантированно возвращаются в том порядке, в котором мы их вызвали.Однако я подозреваю, что Rx справляется с этим гораздо более элегантно.Но я не могу заставить его работать.Вот что у меня есть до сих пор ...

myCollection.Add(new myObject(1));
myCollection.Add(new myObject(2));
myCollection.Add(new myObject(3));
myCollection.Add(new myObject(4));
myCollection.Add(new myObject(5));
myCollection.Add(new myObject(6));

foreach (var myItem in myCollection)
{
    var myObservable = Observable.FromEventPattern<MyServiceMethodCompletedEventArgs>
    (
        f => myServiceClient.MyServiceMethodCompleted += f,
        f => myServiceClient.MyServiceMethodCompleted -= f
    ).Take(1).ObserveOn(SynchronizationContext.Current);

    myObservable.Subscribe
    (
    s =>
    {
        if (s.EventArgs.Error == null)
        {

        myItem.MyProperty = s.EventArgs.Result;
        }
    }
    );

    myServiceClient.MyServiceMethodAsync(myItem);
}

Я надеюсь, что вы видите, чего я пытаюсь достичь здесь ...

Все, что я в итоге получаю, это все myObject устанавливается на результат первого вызова, который возвращает.

Я уверен, что это что-то глупое, но я пока не смог понять это.

Спасибо:)

1 Ответ

4 голосов
/ 21 июля 2011

Попробуйте использовать Observable.FromAsyncPattern вместо Observable.FromEventPattern. Есть хитрость в использовании FromAsyncPattern в Silverlight (и в телефоне), потому что пара BeginInvoke / EndInvoke не предоставляется непосредственно прокси-сервером службы. Однако, если вы используете интерфейс для прокси службы, а не сам прокси службы, вы можете получить доступ к шаблону начала / конца:

IMyService svc = new myServiceClient();
var svcObservable = Observable.FromAsyncPattern<T, MyServiceResultArgs>
                        (svc.BeginMyServiceMethod, svc.EndMyServiceMethod);

Теперь вы можете переключиться с использования foreach (антишаблон с LINQ) на превращение myCollection в наблюдаемую и SelectMany между myCollection и запросом на обслуживание следующим образом:

var requestResult = from myItem in myCollection.ToObservable()
                    from result in svcObservable(myItem)
                    select new {myItem, result};

requestResult.Subscribe(result => result.myItem.myProperty = result.result);

Еще одно предостережение: если вы используете FromAsyncPattern в silverlight таким образом, результат вернется в фоновом потоке. Вам нужно будет позаботиться о том, чтобы делегат вернулся к диспетчеру.

Если вы хотите увидеть это в действии, посмотрите последние 20 минут моей презентации Mix на http://channel9.msdn.com/events/MIX/MIX11/EXT08.

...