我有一个WPF应用程序,其中视图模型中的一个属性将被填充为对服务的调用。到目前为止,我一直在关注Stephen Cleary的优秀教程。他讨论了一种做法here
的方法在我的情况下,视图模型每个应用程序实例化一次。应用程序在视图模型上调用Initialise方法(自定义方法),传递一些信息,View模型应该根据这些信息与服务联系以获取实例化的属性。
问题是应用程序可以多次调用Initialise方法(用户随机移动)传入新的信息集。当发生这种情况时,我需要丢弃之前调用Initialise时调用的早期运行任务(如果有的话),使用新的信息集调用服务,并确保该属性仅绑定到最新调用的结果。
有人可以提出一个模式来实现这一目标吗?基本上多次调用异步方法,但只保留最后的结果。
答案 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>