如何按顺序 运行 任务并将结果放入 IObservable
How to sequentially run Tasks and put the result in IObservable
在我的 ViewModel 中,我想做几件事,并想在事情完成时更新状态。
Kent Boogaart 的书建议使用 Observable 来显示进度。我现在被困在如何做多项工作,比如在 Task
s 中,然后勾选可观察对象。我尝试了 Concat
运算符,但所有 Task
都立即开始,而不是一个接一个地开始。
public class StartupViewModel : ReactiveObject
{
public string Status { [ObservableAsProperty]get; }
public ReactiveCommand<Unit,string> LoadedCommand { get; set; }
public StartupViewModel()
{
var progress = Observable.Concat(
Task.Run(() =>
{
Thread.Sleep(3000);
return "hello";
}).ToObservable(),
Task.Run(() =>
{
Thread.Sleep(3000);
return "cip";
}).ToObservable(),
Task.Run(() =>
{
Thread.Sleep(3000);
return "2040";
}).ToObservable()
);
LoadedCommand = ReactiveCommand.CreateFromObservable(() => progress);
LoadedCommand
.ToPropertyEx(this, x => x.Status, "Starting up, please be patient");
}
}
可能你可以像
return Observable.Create<string>(async (obs, cancellationToken) =>
{
obs.OnNext(await Task1(cancellationToken));
obs.OnNext(await Task2(cancellationToken));
obs.OnNext(await Task3(cancellationToken));
obs.OnCompleted();
});
问题是您正在启动 Concat
构造中的所有任务。 Concat
正在做正确的事情并从所有已完成的任务中获取结果。您想要做的是将任务包装在 Obserable.Defer
中,这样它们就不会一次全部启动,而只会在它们被 Concat
运算符订阅时启动:
var progress = Observable.Concat(
Observable.Defer (() => Task.Run(() => { Thread.Sleep(5000); return 1; }).ToObservable()),
Observable.Defer (() => Task.Run(() => { Thread.Sleep(5000); return 2; }).ToObservable())
);
在我的 ViewModel 中,我想做几件事,并想在事情完成时更新状态。
Kent Boogaart 的书建议使用 Observable 来显示进度。我现在被困在如何做多项工作,比如在 Task
s 中,然后勾选可观察对象。我尝试了 Concat
运算符,但所有 Task
都立即开始,而不是一个接一个地开始。
public class StartupViewModel : ReactiveObject
{
public string Status { [ObservableAsProperty]get; }
public ReactiveCommand<Unit,string> LoadedCommand { get; set; }
public StartupViewModel()
{
var progress = Observable.Concat(
Task.Run(() =>
{
Thread.Sleep(3000);
return "hello";
}).ToObservable(),
Task.Run(() =>
{
Thread.Sleep(3000);
return "cip";
}).ToObservable(),
Task.Run(() =>
{
Thread.Sleep(3000);
return "2040";
}).ToObservable()
);
LoadedCommand = ReactiveCommand.CreateFromObservable(() => progress);
LoadedCommand
.ToPropertyEx(this, x => x.Status, "Starting up, please be patient");
}
}
可能你可以像
return Observable.Create<string>(async (obs, cancellationToken) =>
{
obs.OnNext(await Task1(cancellationToken));
obs.OnNext(await Task2(cancellationToken));
obs.OnNext(await Task3(cancellationToken));
obs.OnCompleted();
});
问题是您正在启动 Concat
构造中的所有任务。 Concat
正在做正确的事情并从所有已完成的任务中获取结果。您想要做的是将任务包装在 Obserable.Defer
中,这样它们就不会一次全部启动,而只会在它们被 Concat
运算符订阅时启动:
var progress = Observable.Concat(
Observable.Defer (() => Task.Run(() => { Thread.Sleep(5000); return 1; }).ToObservable()),
Observable.Defer (() => Task.Run(() => { Thread.Sleep(5000); return 2; }).ToObservable())
);