如何取消IMvxAsyncCommand?

时间:2019-11-14 11:26:21

标签: xamarin.android mvvmcross

我刚开始在MVVMcross平台上使用xamarin android。我需要取消IMvxAsyncCommand,但是我尝试了很多方法,但仍然无法正常工作。有人对此有任何想法或样本吗?

2 个答案:

答案 0 :(得分:1)

实际上,您可以直接取消MvxAsyncCommand,而无需创建任何其他CancellationTokenSource

只需在对象本身上调用Cancel()

因此,不要使用ICommandIMvxCommand来使属性为MvxAsyncCommandIMvxAsyncCommand

这样,当您在CancellationToken中有一个Task作为参数,并在命令上调用Cancel()时,它将取消该令牌。

private async Task MyAsyncStuff(CancellationToken ct)
{
    await abc.AwesomeAsyncMethod(ct);
    // and/or
    ct.ThrowIfCancellationRequested();
}

因此,如果您修改@fmaccaroni的答案,则会得到以下信息:

public class MyClass
{    
    public MyClass()
    {
        MyAsyncCommand = new MvxAsyncCommand(MyAsyncStuff);
        CancelMyTaskCommand = new MvxCommand(() => MyAsyncCommand.Cancel());
    }

    public IMvxAsyncCommand MyAsyncCommand {get; private set; }

    public ICommand CancelMyTaskCommand { get; private set; }

    private async Task MyAsyncStuff(CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        await foo.BlablaAsync();

        cancellationToken.ThrowIfCancellationRequested();

        await bar.WhateverAsync();

        cancellationToken.ThrowIfCancellationRequested();

        await foo2.AnotherAsync();
    }
}

编辑:或者,如果您的异步方法还允许直接通过CancellationToken取消它们,则MyAsyncStuff方法可以写为:

private async Task MyAsyncStuff(CancellationToken cancellationToken)
{
    await foo.BlablaAsync(cancellationToken);
    await bar.WhateverAsync(cancellationToken);
    await foo2.AnotherAsync(cancellationToken);
}

或者,如果您不在乎它们的开始顺序和完成顺序,

private Task MyAsyncStuff(CancellationToken cancellationToken)
{
    return Task.WhenAll(
        foo.BlablaAsync(cancellationToken),
        bar.WhateverAsync(cancellationToken),
        foo2.AnotherAsync(cancellationToken));
}

答案 1 :(得分:0)

因此,基本上IMvxAsyncCommand只是这样调用Task

MyCommand = new MvxAsyncCommand(MyTask);
...
private async Task MyTask()
{
     // do async stuff
}

要取消Task,您需要使用CancellationToken,可以从CancellationTokenSource获取它,并使用其他命令或任何您想调用的{{1 }}放在Cancel()上,因此您可以采用的一种方法是:

CancellationTokenSource

然后,您可以改进代码,以避免重复调用public class MyClass { private CancellationTokenSource cts; public MyClass() { MyAsyncCommand = new MvxAsyncCommand(MyTask); CancelMyTaskCommand = new MvxCommand(() => cts.Cancel()); } public ICommand MyAsyncCommand {get; private set; } public ICommand CancelMyTaskCommand { get; private set; } private async Task MyTask() { cts = new CancellationTokenSource(); await MyAsyncStuff(cts.CancellationToken); cts.Dispose(); cts = null; } private async Task MyAsyncStuff(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); await foo.BlablaAsync(); cancellationToken.ThrowIfCancellationRequested(); await bar.WhateverAsync(); cancellationToken.ThrowIfCancellationRequested(); await foo2.AnotherAsync(); } } ,处理取消异常,使用MvxNotifyTask和许多其他操作,但这是基础。

Cancellation in Managed Threads中的更多信息 HIH