С такими вещами вы всегда хотите выйти наизнанку.Самое сложное в переводе это части между асинхронными вызовами.Если бы вы передавали результат одного прямо в другой, это было бы просто from x in async1() from y in async2(x) ...
.Я вижу две функции, на которые я бы разбил это:
public IObserservable<string> UpdateCachedClients(object param)
{
var getCachedClientsAsync = Observable.FromAsyncPattern<...>(service.BeginGetCachedClients, service.EndGetCachedClients);
var updateClientsAsync = Observable.FromAsyncPattern<...>(service.BeginUpdateClients, service.EndUpdateClients);
return Observable.Create<string>(obs =>
{
return (from r2 in getCachedClientsAsync(param)
.Do(v =>
{ if (CheckResult(v))
obs.OnNext("clients valid");
else
obs.OnNext("clients not valid");
//huh? is this done twice
UpdateClients(v);
})
from b in updateClientsAsync(r2)
select (b ? "clients updated" : "clients not updated")
).Subscribe(obs);
});
}
public IObservable<string> UpdateAllClients(object param)
{
var getClientsAsync = Observable.FromAsyncPattern<...>(service.BeginGetClients, service.EndGetClients);
return from r in getClientsAsync(param)
select (CheckResult(r) ?
Observable.Return("error on get clients") :
UpdateCachedClients(param));
}
Я использовал дополнительный слой Observable.Create
в первой функции, потому что это казалось самым простым способом передать результат и перейти к следующему вызову.,Если у вас есть эти две функции, вы сможете вызывать их следующим образом:
IsBusy = true;
var disp = UpdateAllClients(param)
.Subscribe(ShowMessage,
ex => IsBusy = false,
() => IsBusy = false);
Обратите внимание, что я установил для IsBusy
значение false как в OnError, так и в OnCompleted, поскольку любое из них является завершающим сообщением дляIObservable.
TPL кажется более естественным подходом для асинхронных методов, подобных этому, так как они выдают только одно значение, но до следующей версии языков с async / await вы, вероятно, получите синтаксис, аналогичный любомуваш метод или мой, если вы используете Tasks вместо IObservables.