如何使用Dispatcher设置Image.Source属性?

6

我尝试使用以下建议:http://msdn.microsoft.com/en-us/library/ms741870.aspx(“使用后台线程处理阻塞操作”)。

这是我的代码:

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ;
        }

        private void Process()
        {
            // some code creating BitmapSource thresholdedImage

            ThreadStart start = () =>
            {
                Dispatcher.BeginInvoke(
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new Action<ImageSource>(Update),
                    thresholdedImage);
            };
            Thread nt = new Thread(start);
            nt.SetApartmentState(ApartmentState.STA);
            nt.Start();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            button1.IsEnabled = false;
            button1.Content = "Processing...";

            Action action = new Action(Process);
            action.BeginInvoke(null, null);
        }

        private void Update(ImageSource source)
        {
            this.image1.Source = source; // ! this line throw exception

            this.button1.IsEnabled = true; // this line works
            this.button1.Content = "Process"; // this line works
        }
    }

在标记的行中,它会抛出InvalidOperationException "由于调用线程无法访问此对象,因为不同的线程拥有它"。但是,如果我删除这行代码,应用程序将可以正常工作。
XAML:
<!-- language: xaml -->
    <Window x:Class="BlackZonesRemover.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="clr-namespace:BlackZonesRemover"
            Title="MainWindow" Height="600" Width="800" Loaded="Window_Loaded">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Border Background="LightBlue">
                <Image Name="image1" Stretch="Uniform" />
            </Border>
            <Button Content="Button" Grid.Row="1" Height="23" Name="button1" Width="75" Margin="10" Click="button1_Click" />
        </Grid>
    </Window>

图片的Source属性和按钮的IsEnabled和Content属性有什么不同?我该怎么做?
2个回答

10

具体建议: thresholdImage 是在后台线程上创建的。请在UI线程上创建它,或者一旦创建就将其冻结。

一般建议: 区别在于ImageSource是一个DependencyObject,因此它具有线程关联性。因此,您需要在与分配它的Image相同的线程(即UI线程)上创建ImageSource,或者在创建后需要Freeze(),这样可以允许任何线程访问它。


4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接