多次调用异步方法

时间:2014-09-24 11:57:01

标签: c# task-parallel-library

我有一个WPF应用程序,其中视图模型中的一个属性将被填充为对服务的调用。到目前为止,我一直在关注Stephen Cleary的优秀教程。他讨论了一种做法here

的方法

在我的情况下,视图模型每个应用程序实例化一次。应用程序在视图模型上调用Initialise方法(自定义方法),传递一些信息,View模型应该根据这些信息与服务联系以获取实例化的属性。

问题是应用程序可以多次调用Initialise方法(用户随机移动)传入新的信息集。当发生这种情况时,我需要丢弃之前调用Initialise时调用的早期运行任务(如果有的话),使用新的信息集调用服务,并确保该属性仅绑定到最新调用的结果。

有人可以提出一个模式来实现这一目标吗?基本上多次调用异步方法,但只保留最后的结果。

1 个答案:

答案 0 :(得分:1)

基本上,您要取消之前调用的Initialize方法。在TPL中,如果你想取消某些内容,通常应该使用CancellationToken

这样做的方法是在视图模型中使用CancellationTokenSource类型的字段,表示取消上次调用Initialize。当您运行Initialize时,它会取消之前的调用,设置自己的取消,调用服务,然后仅在未请求取消时设置属性。在代码中:

class ViewModel
{
    // default value just to avoid a null check
    private CancellationTokenSource intializationCancellation =
        new CancellationTokenSource();

    public async Task InitializeAsync(int parameter)
    {
        // cancel previous initialization, if any
        intializationCancellation.Cancel();

        var cts = new CancellationTokenSource();
        intializationCancellation = cts;

        var value = await GetValueaAsync(parameter);

        if (cts.Token.IsCancellationRequested)
            return;

        Value = value;
    }

    private async Task<string> GetValueAsync(int parameter)
    {
        // call the external service here
    }

    public string Value { get; private set; }
}

如果您要拨打的服务支持取消,您应该将CancellationToken传递给它,这可能会节省一些资源。如果你这样做,请不要忘记抓住结果OperationCanceledException(因为我相信你不想要Initialize投掷,即使它被取消了。 / p>