取消属性

时间:2016-06-23 11:24:14

标签: c# mvvm async-await uwp

我正在开发一个UWP MVVM应用程序,它通过位置解析地址:

private async void ResolveAddress()
{
    //TODO : Manage cancel
    Debug.WriteLine("Resolving adress ...");
    var result = await MapLocationFinder.FindLocationsAtAsync(SelectedLocation);
    if (result.Status == MapLocationFinderStatus.Success)
    {
        if (result.Locations.Count > 0)
        {
            Debug.WriteLine("Adress resolved : " + Address);
            Address = result.Locations[0].Address.FormattedAddress;
        }
    }
    Debug.WriteLine("Resolve fail");
}

此呼叫可能经常发生(基于用户选择的位置),因此当进行其他呼叫时,该方法可能尚未完成运行。

//Binding property
public Geopoint SelectedLocation
{
    get { return _selectedLocation; }
    set
    {
        Debug.WriteLine("Location change");
        _selectedLocation = value;
        ResolveAddress();
        RaisePropertyChanged();
    }
}

Adress字段也是一个绑定属性。

我遇到了这个实现的2个问题:

  • 我不确定Adress字段是否为最后选择的位置(N之后的呼叫N-1可以完成)。
  • 地址字段包含已解决的所有地址,我只想要最后一个地址。

我找到了取消异步任务的方法:

https://msdn.microsoft.com/fr-fr/library/jj155759.aspx

但MapLocationFinder.FindLocationsAtAsync在参数中没有取消令牌。

实现这一目标的最佳方法是什么?

感谢。

1 个答案:

答案 0 :(得分:0)

  

我不确定Adress字段是否为最后选择的位置(N之后的呼叫N-1可以完成)。

您可以使用asynchronous callback token解决此问题。我在一篇非常古老的博文中更详细地描述了它,我称之为“异步回调上下文”。鉴于今天“上下文”这个术语过载,我现在更喜欢术语“令牌”。

private object _addressCallbackToken;

private async void ResolveAddress()
{
  Debug.WriteLine("Resolving adress ...");
  var token = _addressCallbackToken = new object();
  var result = await MapLocationFinder.FindLocationsAtAsync(SelectedLocation);
  if (token != _addressCallbackToken)
    return;
  if (result.Status == MapLocationFinderStatus.Success)
  {
    if (result.Locations.Count > 0)
    {
      Debug.WriteLine("Adress resolved : " + Address);
      Address = result.Locations[0].Address.FormattedAddress;
    }
  }
  Debug.WriteLine("Resolve fail");
}

但是,我强烈建议不要以这种方式使用async void。您可能会发现async MVVM data binding上的文章很有用。