简体   繁体   English

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

[英]How to set Image.Source property with Dispatcher?

I tried use this recomendations: http://msdn.microsoft.com/en-us/library/ms741870.aspx ("Handling a Blocking Operation with a Background Thread").我尝试使用以下建议: http://msdn.microsoft.com/en-us/library/ms741870.aspx (“使用后台线程处理阻塞操作”)。

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.".在标记的行中,它抛出 InvalidOperationException “由于调用线程无法访问此 object,因为不同的线程拥有它。”。 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? Image.Source 属性与 Button.IsEnabled 和 Button.Content 属性有什么区别? What can I do?我能做些什么?

Specific advice: thresholdImage is being created on a background thread.具体建议: thresholdImage正在后台线程上创建。 Either create it on the UI thread, or freeze it once it has been created.要么在 UI 线程上创建它,要么在创建后将其冻结。

General advice: The difference is that ImageSource is a DependencyObject so it has thread affinity.一般建议:不同之处在于ImageSource是一个DependencyObject ,因此它具有线程关联性。 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.因此,您需要在与您分配它的Image相同的线程上创建ImageSource (即 UI 线程),或者您需要在创建ImageSource后对其进行Freeze() ,从而允许任何线程访问它。

The problem is because thresholdedImage is created in the background thread and used on UI thread.问题是因为thresholdedImage是在后台线程中创建并在 UI 线程上使用的。

Calling Freeze method might help.调用 Freeze 方法可能会有所帮助。 See Updating an Image UI property from a BackgroundWorker thread请参阅从 BackgroundWorker 线程更新图像 UI 属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM