C# 多次调用异步方法

C# 多次调用异步方法,c#,task-parallel-library,C#,Task Parallel Library,我有一个WPF应用程序,其中视图模型中的一个属性将作为对服务的调用填充。到目前为止,我一直在关注斯蒂芬·克利里的优秀教程。他讨论了这样做的一种方法 在我的例子中,视图模型在每个应用程序中实例化一次。应用程序在视图模型上调用Initialise方法(自定义方法),传递一些信息,视图模型应该根据这些信息接触服务以实例化属性 问题是应用程序可以多次调用Initialise方法(用户随机移动)传递新的信息集。发生这种情况时,我需要放弃在上次调用初始化时调用的早期运行任务(如果有),使用新的信息集调用服务

我有一个WPF应用程序,其中视图模型中的一个属性将作为对服务的调用填充。到目前为止,我一直在关注斯蒂芬·克利里的优秀教程。他讨论了这样做的一种方法

在我的例子中,视图模型在每个应用程序中实例化一次。应用程序在视图模型上调用Initialise方法(自定义方法),传递一些信息,视图模型应该根据这些信息接触服务以实例化属性

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


有人能帮忙想出一个模式来实现这一点吗?基本上,多次调用异步方法,但只保留最后一个结果。

基本上,您希望取消先前对
Initialize
方法的调用。在第三方物流中,如果你想取消某些东西,通常应该使用
CancellationToken

这里的方法是在视图模型中有一个类型字段,表示取消上次调用
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; }
}
类视图模型
{
//默认值只是为了避免空检查
私有取消令牌源初始化取消=
新的CancellationTokenSource();
公共异步任务InitializeAsync(int参数)
{
//取消以前的初始化(如果有)
初始化取消。取消();
var cts=新的CancellationTokenSource();
初始化取消=cts;
var值=等待GetValueaAsync(参数);
如果(cts.Token.IsCancellationRequested)
返回;
价值=价值;
}
专用异步任务GetValueAsync(int参数)
{
//在这里呼叫外部服务
}
公共字符串值{get;private set;}
}

如果您呼叫的服务支持取消,您也应该将
CancellationToken
传递给它,这可能会节省一些资源。如果这样做,请不要忘记捕获生成的
OperationCanceledException
(因为我相信您不希望
Initialize
抛出,即使它已被取消)。

您会同时调用它们多次吗?或者您的应用程序会多次调用
Initialize
方法,但调用之间存在差异?当用户单击按钮时会调用initialise方法,因此调用将不是并发的,而是顺序的。您的答案是文本正确的,但并不真正适用于我的问题。考虑到我还必须处理的高级别COM互操作,没有一种直接的模式可以帮助解决这个问题。事情也很复杂,因为我需要确保运行任务的线程是STA,而TPL不能保证。总的来说,我需要重新设计一点,但我现在的工作符合我的要求。无论如何谢谢你!