C# 如何使用ReactiveUI正确取消ViewModel停用时的任务?
在我的MVVM应用程序中,当一个ViewModel被激活时,一个任务开始建立网络连接,可能需要一些时间才能完成。此任务是可取消的:C# 如何使用ReactiveUI正确取消ViewModel停用时的任务?,c#,mvvm,system.reactive,reactiveui,C#,Mvvm,System.reactive,Reactiveui,在我的MVVM应用程序中,当一个ViewModel被激活时,一个任务开始建立网络连接,可能需要一些时间才能完成。此任务是可取消的: private async Task ConnectAsync(CancellationToken cancellationToken = default) { ... } 我使用IActivatableViewModel在ViewModel激活时启动它,如下所示: // Constructor: public SomeViewModel(...) {
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
()。如果你这样做,你会得到一些额外的好处,比如订阅ThrownExceptions
和IsExecuting
observables,然后显示一些加载指示器或错误消息,让用户了解应用程序正在做什么。此外,按照描述的模式,您可以通过另一个命令或事件取消该ReactiveCommand
。通过事件取消将如下所示:
//ViewModel.cs
Cancel=ReactiveCommand.Create(()=>{});
Connect=反应命令
.CreateFromObservable(
()=>可观察
.StartAsync(ConnectAsync)
.TakeUntil(取消));
//View.xaml.cs
当激活时(一次性=>{
this.Events()//启动长时间运行的操作
.装载
.Select(args=>Unit.Default)
.InvokeCommand(ViewModel,x=>x.Connect)
.处置(一次性);
this.Events()//停止长时间运行的操作
.卸货
.Select(args=>Unit.Default)
.InvokeCommand(ViewModel,x=>x.Cancel)
.处置(一次性);
});
这里,我假设ConnectAsync
是一种接受取消令牌并返回任务的方法。要启用this.Events()
magic,您需要使用或安装其中一个软件包。但是无论如何,如果您希望在激活时依赖,ThrownExceptions
,IsExecuting
等,那么您的选项看起来也不错。如果您希望使用命令并依赖WhenActivated
,那么请修改视图.xaml.cs
代码:
//View.xaml.cs
当激活时(一次性=>{
Connect.Execute().Subscribe();
可任意处理的
.Create(()=>Cancel.Execute().Subscribe())
.处置(一次性);
});
我们不会处理由Execute()
返回的订阅,因为当命令完成执行时,它们无论如何都会被处理掉。希望这有帮助!✨ 我想没问题,非常感谢,我喜欢这个解决方案,它更强大、更干净。但因为我使用的是Avalonia UI,我可能不得不等待在下一次预览中发布。在阿瓦隆尼亚的情况下,我可以使用哪种事件?加载/卸载在那里似乎不存在?AttachedToVisualTree?启动时
在引擎盖下使用AttachedToVisualTree
,因此在您的情况下,我想不需要这个.Events()
。另外,this.Events()
如果您像这样安装Pharmacialist
,将变得可用。同样Avalonia.ReactiveUI.Events
也应该在Avalonia每晚构建提要中可用