kennyzx
kennyzx

Reputation: 12993

Using BitmapImage created on Threadpool thread

I get an "invalid cross-thread access" exception when trying to set an image using a BitmapImage instance created on a ThreadPool thread.

It turns out to avoid this I have to create the BitmapImage instance on the UI thread. But generating the BitmapImage is time-consuming (takes 100ms or even longer, here it is loaded from a file just for the purpose of demostration), that is why I want to do it on a ThreadPool thread.

If I instantiate the BitmapImage instance on the UI thread, and pass a reference to the ThreadPool thread to manipulate it (like setting pixels), I have to Marshal back to the UI thread to access the BitmapImage, that will freeze the UI thread and that is exactly what I am trying to avoid.

Suggestions?

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem((o) =>
        {
            var bitmapImage = new BitmapImage(new Uri("default.jpg", UriKind.Relative));
            TryToSetImage(bitmapImage);
        });
    }

    private void TryToSetImage(object obj)
    {
        if (this.Dispatcher.CheckAccess())
        {
            //Exception: The calling thread cannot access this object because a different thread owns it.
            image1.Source = obj as BitmapImage; 
        }
        else
        {
            this.Dispatcher.Invoke(new WaitCallback(TryToSetImage),
                System.Windows.Threading.DispatcherPriority.Render,
                obj);
        }
    }

Upvotes: 2

Views: 1638

Answers (1)

brunnerh
brunnerh

Reputation: 184476

You need to Freeze it after creating it to make accessible for other threads.

Upvotes: 2

Related Questions