Hi,

In my main wpf Window I instantiate a new wpf window at a click of a button, that collects a bunch of data. This data is stored in a class object (see below).
Now when I try to pass this class to a backgroundworker I get the well-known “The calling thread cannot access this object because a different thread owns it.” error.

I can’t see how I can get around this problem. I feel I have tried every possible permutation without success.

The data are as follows:

internal int screenHeightInPixels;
internal int screenWidthInPixels;
internal double screenHeightInDpi;
internal double screenWidthInDpi;
internal List<System.Windows.Shapes.Rectangle> rAreas = new List<System.Windows.Shapes.Rectangle>();
internal Ellipse eAreas = new Ellipse();
internal List<System.Drawing.Color> Colors = new List<System.Drawing.Color>();

The call

SimpleThread.RunWorkerAsync(selector.selectedData);

Where selector is the instantiation of the Selector window that retrived the data.

To test, in the DoWork I start with the following, which results in the error, in the second line.

selectedData = (SelectedData)(((SelectedData)e.Argument));
double d = selectedData.areas[0].Width;

Hope this is a trivial problem for a great mind out there.

Thanks
- hmortensen

It seems to me, that this is because your object was created in your data collection window's UI thread and has been attached to UI elements (intentionally or not)

What I suggest is making a copy of the class before you pass it to the async worker and pass your local copy to the async worker instead.

Also, if you are updating the UI from the worker somewhere, remember any changes must be made via the Dispatcher.

Edited 5 Years Ago by Ketsuekiame: n/a

Sorry, it didn't work. I made a deep copy of the class to be passed as argument, before calling RunWorkerAsync..
It looks to be something to do with the "System.Windows.Shapes" objects..

I do not make any changes to the UI, only reading from the passed in selectedData class.

Any ideas? :/

Hi,
Use this on your form_load event

Control.CheckForIllegalCrossThreadCalls = false;

Hope it will help you.

Edited 5 Years Ago by bhagawatshinde: n/a

Ok, I found a solution, not pretty but it works..
Instead of making a direct copy of the selectedData class I made a new class the do not contain any "System.Windows.Shapes", and copy the data into that class before calling RunWorkerAsync.
New Class:

public int screenWidthInPixels;
        public int screenHeightInPixels;
        public double screenWidthInDpi;
        public double screenHeightInDpi;
        public List<System.Drawing.Rectangle> rAreas = new List<System.Drawing.Rectangle>();
        public List<System.Drawing.Color> Colors = new List<System.Drawing.Color>();
        public System.Drawing.Point eArea = new System.Drawing.Point();

Now there isn't any problem at all?
What is so special about the Shapes, that makes them thread bastards?
Still, if anyone have a better solution, then please write..

- hmortensen

Ok, I found a solution, not pretty but it works..
Now there isn't any problem at all?
What is so special about the Shapes, that makes them thread bastards?
Still, if anyone have a better solution, then please write..

- hmortensen

The Shapes class inherits UIElement from FrameworkElement. MSDN Link

This will force it to attach to the creating thread (which is your UI thread) as I noted in my first post =)

A better way is to not include UI Elements in your class data if at all possible. If needs be, create another class or struct to hold the data and use this data to construct your Shape class on the UI.

The other way is to use the Dispatcher to move back onto your UI thread but this removes most if not all of the benefit of using Async calls.

Comments
Got to the core of the problem in a few lines

Thanks I must have overlooked "and has been attached to UI elements (intentionally or not)" i your initial post.

It makes sense. I'll just use my new shape free class.

Thanks for all your help.

This question has already been answered. Start a new discussion instead.