开发者

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").

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 acti开发者_JAVA百科on = 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?


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜