图像的异步数据绑定会导致跨线程异常

时间:2013-01-17 09:00:55

标签: wpf data-binding asynchronous datagridview bitmapsource

我的WPF应用程序出了问题。 我正在尝试使用viewmodel中的image属性在我的gridview中对图像字段进行数据绑定。

<DataGridTemplateColumn Header="Image" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Image Source="{Binding Path=Image, IsAsync=True}" />
    </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

如果我不使用IsAsync,这没问题。 但是,我想做异步,因为它需要加载大量图像,并且需要从Web服务加载它们。

Image属性的代码是this,它只调用一个调用web服务的处理程序dll。

    public BitmapSource Image
    {
        get { return image ?? (image = ImageHandler.GetDefaultImages(new[] {ItemNumber},160,160)[0].BitmapSource()); }
    }

但是,只要我添加IsAsync = true,我就会在表单加载后得到以下异常:

The calling thread cannot access this object because a different thread owns it.

我是WPF的新手,我有点假设,当异步设置为true时,它处理了线程本身。在数据绑定中是否需要以某种方式调用? 如果是这样,我该怎么做呢?

2 个答案:

答案 0 :(得分:6)

IsAsync表示将从另一个线程访问绑定属性,因此请确保您创建的任何内容都可以以跨线程方式使用。绑定的最后一步将始终发生在主线程上。

WPF中的几乎所有类都继承自DispatcherObject,它基本上将对象“链接”到当前线程创建时。代码中的BitmapSource是在另一个线程上创建的,然后无法在主UI线程上使用。

但是,BitmapSource继承自Freezable:只需在返回之前调用BitmapSource上的Freeze方法,以使其在任何线程中都不可变且可用。

答案 1 :(得分:0)

如果您在单独的线程上访问图像并且不使用IsAsync,那该怎么办?像

这样的东西
public BitmapSource Image
    {
        get 
        { 
            return image ?? (Task.Factory.StartNew(() => image = ImageHandler.GetDefaultImages(new[] { ItemNumber }, 160, 160)[0].BitmapSource());) 
        }
    }