如何解决如何使用ReactiveUI正确取消ViewView停用任务?
在我的MVVM应用程序中,当激活ViewModel时,将启动一个Task,该Task建立一个网络连接,并且可能需要一些时间才能完成。此任务是可扩展的:
private async Task ConnectAsync(CancellationToken cancellationToken = default)
{
...
}
我正在使用IActivatableViewModel
这样在ViewModel激活中启动它:
// Constructor:
public SomeViewModel(...)
{
this.WhenActivated(disposable => {
Observable.StartAsync(ConnectAsync);
});
}
现在,当在任务完成之前停用ViewModel时,建议取消该长期运行任务的方法是什么?
我想到了这个
this.WhenActivated(disposable => {
Observable.StartAsync(ConnectAsync).Subscribe().DisposeWith(disposable);
});
这是正确的解决方案还是有更好的解决方案?
提前谢谢!
解决方法
是的,您在代码段中显示的代码看起来不错。但是,可能值得将ConnectAsync
方法调用移至ReactiveCommand<TInput,TOutput>
(docs)。如果执行此操作,则会获得诸如订阅ThrownExceptions
和IsExecuting
可观察对象的特权,然后显示一些加载指示符或错误消息,以使用户随时了解应用程序的运行情况。另外,按照here描述的模式,您可以通过其他命令或事件取消该ReactiveCommand<TInput,TOutput>
。通过事件取消看起来像这样:
// ViewModel.cs
Cancel = ReactiveCommand.Create(() => { });
Connect = ReactiveCommand
.CreateFromObservable(
() => Observable
.StartAsync(ConnectAsync)
.TakeUntil(Cancel));
// View.xaml.cs
this.WhenActivated(disposable => {
this.Events() // Launch the long-running operation
.Loaded
.Select(args => Unit.Default)
.InvokeCommand(ViewModel,x => x.Connect)
.DisposeWith(disposable);
this.Events() // Stop that long-running operation
.Unloaded
.Select(args => Unit.Default)
.InvokeCommand(ViewModel,x => x.Cancel)
.DisposeWith(disposable);
});
在这里,我假设ConnectAsync
是一种接受取消令牌并返回Task
的方法。为了启用this.Events()
魔术,您需要使用Pharmacist或安装ReactiveUI.Events软件包之一。但是无论如何,如果您想依靠WhenActivated
,而不需要ThrownExceptions
,IsExecuting
等,您的选择也很好。如果您想使用命令并依靠{ {1}},然后修改WhenActivated
代码:
View.xaml.cs
我们不会处理// View.xaml.cs
this.WhenActivated(disposable => {
Connect.Execute().Subscribe();
Disposable
.Create(() => Cancel.Execute().Subscribe())
.DisposeWith(disposable);
});
返回的订阅,因为它们会在命令完成执行后被处理。希望这可以帮助! ✨
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。