对WinRT SynchronizationContext感到困惑

时间:2013-07-29 09:17:16

标签: windows-runtime winrt-async

我一直在努力解决奇怪的DataBinding问题,这个问题似乎只发生在WinRT中。我的电话项目使用相同的代码,工作没有问题。

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

更令人困惑的是,我在访问getter时以及setter引发PropertyChanged事件时验证了我在同一个线程(线程3) - 无论代码是什么版。但只有第二个版本才能在下载完成后重新查询Icon propery的效果。

结合:

<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);
  }
}

这个确实如此,但为什么甚至需要捕捉上下文?

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);
  }
}

0 个答案:

没有答案