Windows runtime 对WinRT SynchronizationContext感到困惑

Windows runtime 对WinRT SynchronizationContext感到困惑,windows-runtime,winrt-async,Windows Runtime,Winrt Async,我已经为奇怪的数据绑定问题挣扎了一段时间,这个问题似乎只发生在WinRT中。我的手机项目使用相同的代码,工作没有问题 下面代码的第一个版本在WinRT上不起作用,而第二个版本在WinRT上起作用。令人困惑的是,我假设对“Icon”getter的调用总是来自UI线程,因此用于异步“DownloadIcon”方法的同步上下文将是正确的。但显然不是 更令人困惑的是,我已经验证了在访问getter和setter引发PropertyChanged事件时,我处于同一个线程(线程3),而不管代码版本如何。但只

我已经为奇怪的数据绑定问题挣扎了一段时间,这个问题似乎只发生在WinRT中。我的手机项目使用相同的代码,工作没有问题

下面代码的第一个版本在WinRT上不起作用,而第二个版本在WinRT上起作用。令人困惑的是,我假设对“Icon”getter的调用总是来自UI线程,因此用于异步“DownloadIcon”方法的同步上下文将是正确的。但显然不是

更令人困惑的是,我已经验证了在访问getter和setter引发PropertyChanged事件时,我处于同一个线程(线程3),而不管代码版本如何。但只有第二个版本具有图标属性在下载完成后被重新查询的效果

绑定:

<DataTemplate x:Key="AppBarAlbumItemTemplateGrid">
  <Grid HorizontalAlignment="Left" Width="80" Height="80">
    <Grid.RowDefinitions>
      <RowDefinition Height="*"></RowDefinition>
      <RowDefinition Height="20"></RowDefinition>
    </Grid.RowDefinitions>
    <Border Grid.RowSpan="2" Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
      <Image Source="{Binding Icon}" Stretch="UniformToFill" />
    </Border>
    <Grid Grid.Row="1" VerticalAlignment="Bottom" Background="{StaticResource GIFPlayerOverlayBrush}">
      <TextBlock Text="{Binding Title}" VerticalAlignment="Center" FontSize="10" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Margin="5,0"/>
    </Grid>
  </Grid>
</DataTemplate>

这无法正常工作:

public class Album : AlbumBase
{
  WeakReference<ImageSource> icon;

  public ImageSource Icon
  {
    get
    {
      ImageSource result;
      if (icon != null && icon.TryGetTarget(out result))
        return result;

      DownloadIcon();
      return null;
    }

    private set
    {
        this.RaiseAndSetIfChanged(ref icon, new WeakReference<ImageSource>(value));
    }
  }

  async void DownloadIcon()
  {
      Icon = await imageHelper.LoadImageFromUrlAsync(IconUrl, AppSettings.ThumbnailsFolder);
  }
}
公共类相册:AlbumBase { WeakReference图标; 公共图像源图标 { 得到 { 图像源结果; if(icon!=null&&icon.TryGetTarget(输出结果)) 返回结果; 下载图标(); 返回null; } 专用设备 { this.RaiseAndSetIfChanged(参考图标,新WeakReference(值)); } } 异步void DownloadIcon() { Icon=wait imageHelper.LoadImageFromUrlAsync(IconUrl,AppSettings.ThumbnailsFolder); } } 这一条确实如此,但为什么还要捕捉上下文呢

public class Album : AlbumBase
{
  public Album()
  {
    this.synchronizationContext = SynchronizationContext.Current;
  }

  private SynchronizationContext synchronizationContext;
  WeakReference<ImageSource> icon;

  public ImageSource Icon
  {
    get
    {
      ImageSource result;
      if (icon != null && icon.TryGetTarget(out result))
        return result;

      DownloadIcon();
      return null;
    }

    private set
    {
      this.synchronizationContext.Post((x) =>
      {
        this.RaiseAndSetIfChanged(ref icon, new WeakReference<ImageSource>(value));
      }, null);
    }
  }

  async void DownloadIcon()
  {
      Icon = await imageHelper.LoadImageFromUrlAsync(IconUrl, AppSettings.ThumbnailsFolder);
  }
}
公共类相册:AlbumBase { 公共相册() { this.synchronizationContext=synchronizationContext.Current; } 私有同步上下文同步上下文; WeakReference图标; 公共图像源图标 { 得到 { 图像源结果; if(icon!=null&&icon.TryGetTarget(输出结果)) 返回结果; 下载图标(); 返回null; } 专用设备 { this.synchronizationContext.Post((x)=> { this.RaiseAndSetIfChanged(参考图标,新WeakReference(值)); },空); } } 异步void DownloadIcon() { Icon=wait imageHelper.LoadImageFromUrlAsync(IconUrl,AppSettings.ThumbnailsFolder); } }
第一个版本应该可以工作(尽管我不会这样做)。您是否仔细检查了您的
INotifyPropertyChanged
实现?(应该先设置,然后提出)。@StephenCleary Stephen,尽管我使用的是相当成熟的ReactiveUIs实现,但我编写了自己的实现,以确保它不会修复任何问题(如预期的那样)。出于好奇。你会怎么做?我在我的博客上谈了一些。在这种情况下,我将使用my,它允许对错误条件进行数据绑定并成功(
async void
错误处理不太好)。请尝试启用。希望这能在WinRT上起作用…@StephenCleary PresentationTraceSources似乎在WinRT中不受支持