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

发布于 2024-11-14 22:33:59 字数 2631 浏览 2 评论 0原文

我尝试使用此建议: 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>

Image.Source 属性与 Button.IsEnabled 和 Button.Content 属性之间有什么区别?我能做些什么?

I tried use this recomendations: http://msdn.microsoft.com/en-us/library/ms741870.aspx ("Handling a Blocking Operation with a Background Thread").

This is my code:

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

In marked line it throws InvalidOperationException "due to the calling thread cannot access this object because a different thread owns it.". But application works if I remove this line.

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>

What difference between Image.Source property and Button.IsEnabled and Button.Content properties? What can I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七月上 2024-11-21 22:33:59

具体建议: thresholdImage 正在后台线程上创建。要么在 UI 线程上创建它,要么在创建后冻结它。

一般建议: 区别在于 ImageSourceDependencyObject,因此它具有线程关联性。因此,您需要在与要分配的 Image 相同的线程(即 UI 线程)上创建 ImageSource,或者您需要 Freeze() ImageSource 一旦你创建了它,从而允许任何线程访问它。

Specific advice: thresholdImage is being created on a background thread. Either create it on the UI thread, or freeze it once it has been created.

General advice: The difference is that ImageSource is a DependencyObject so it has thread affinity. Therefore, you need to create the ImageSource on the same thread as the Image to which you're assigning it (ie. the UI thread), or you need to Freeze() the ImageSource once you've created it, thus allowing any thread to access it.

一梦浮鱼 2024-11-21 22:33:59

问题是因为 thresholdedImage 是在后台线程中创建并在 UI 线程上使用的。

调用 Freeze 方法可能会有所帮助。看
从BackgroundWorker线程更新图像UI属性

The problem is because thresholdedImage is created in the background thread and used on UI thread.

Calling Freeze method might help. See
Updating an Image UI property from a BackgroundWorker thread

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文