Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The calling thread cannot access this object because a different thread owns it [duplicate]

Tags:

Why I can't create CroppedBitmap in the following code? I got an exception:

The calling thread cannot access this object because a different thread owns it.

If I change the code to

CroppedBitmap cb = new CroppedBitmap(new WriteableBitmap(bf), new Int32Rect(1, 1, 5, 5));

the exception is gone? why ?

Code 1, an exception at cb.Freeze():

public MainWindow()
{
    InitializeComponent();

    ThreadPool.QueueUserWorkItem((o) =>
        {
            //load a large image file
            var bf = BitmapFrame.Create(
                new Uri("D:\\1172735642.jpg"),
                BitmapCreateOptions.None,
                BitmapCacheOption.None);
            bf.Freeze();
            Dispatcher.BeginInvoke(
                new Action(() =>
                    {
                        CroppedBitmap cb = new CroppedBitmap(bf, new Int32Rect(1,1,5,5));
                        cb.Freeze();
                        //set Image's source to cb....
                    }), 
                    DispatcherPriority.ApplicationIdle);
         }
    );
}

Code 2, works:

    ThreadPool.QueueUserWorkItem((o) =>
    {
        var bf = BitmapFrame.Create(
                new Uri("D:\\1172740755.jpg"),
                BitmapCreateOptions.None,
                //BitmapCreateOptions.DelayCreation,
                BitmapCacheOption.None);
        bf.Freeze();
        var wb = new WriteableBitmap(bf);
        wb.Freeze();
        this.Dispatcher.Invoke(
            new Action(() =>
            {
                var r = new Int32Rect(1, 1, 5, 5);
                CroppedBitmap cb = new CroppedBitmap(wb, r);
                cb.Freeze();
                //set Image's source to cb....
                Image.Source = cb;
            }),
            DispatcherPriority.ApplicationIdle);
    }
);

Code 3, works without WritableBitmap:

ThreadPool.QueueUserWorkItem((o) =>
    {
        var bf = BitmapFrame.Create(
                new Uri("D:\\1172735642.jpg"),
                BitmapCreateOptions.None,
                //BitmapCreateOptions.DelayCreation,
                BitmapCacheOption.None);
        bf.Freeze();
        var bf2 = BitmapFrame.Create(bf);
        bf2.Freeze();

        this.Dispatcher.Invoke(
            new Action(() =>
            {
                var r = new Int32Rect(1, 1, 5, 5);
                BitmapSource cb = new CroppedBitmap(bf2, r);
                cb.Freeze();
                //set Image's source to cb....
                Image.Source = cb;
            }),
            DispatcherPriority.ApplicationIdle);
    }
);
like image 274
zunyite Avatar asked Apr 28 '10 11:04

zunyite


1 Answers

Following code might help you solve the issue of updating a gui element from another thread :

Module level

delegate void updateCallback(string tekst);

This is the method to update your element :

private void UpdateElement(string tekst)
{
    if (element.Dispatcher.CheckAccess() == false)
    {
        updateCallback uCallBack = new updateCallback(UpdateElement);
        this.Dispatcher.Invoke(uCallBack, tekst);
    }
    else
    { 
//update your element here
    }
 }
like image 52
Terry Avatar answered Sep 24 '22 17:09

Terry