views:

81

answers:

4

I have a "List" in the main application and I am trying to access its elements from within a thread. I am getting this exception: {"The calling thread cannot access this object because a different thread owns it."} System.SystemException {System.InvalidOperationException}

A: 

You are trying to access the UI from a non-UI thread.

Read this: http://www.codeproject.com/Messages/2927256/Re-WPF-Delegates-The-calling-thread-cannot-access-.aspx

and this: http://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher

cornerback84
Thanks, but I am able to set a value to a list member. I don't know how to retrieve a value of it using the dispatcher.
phm
+4  A: 

You can use cross thread by declaring a delegate.

private delegate void thread_delegate();

then create a method and put all your methods that access your list.

private void SampleMethod()
{
....
}

then create a method for your thread. Inside that method invoke your method whick

private void ThreadMethod()
{

           thread_delegate d = new thread_delegate(SampleMethod);
            d.Invoke();
}

On your statement where you create your thread...

 Thread t = new Thread(new ThreadStart(ThreadMethod));    
 t.Start();
Renji Gyouro
I already tried this approach, and it doesn't work. I get the same exception
phm
+2  A: 
DispatcherOperation d = myListBox.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => 
{ 
    // access your listbox and return something
})); 

Then demand your DispatcherOperation for the return value

myValue = d.Result; //Result is of type Object
Veer
Thanks for the solution. My list is a List<Bitmap Image> and the application freezes when I am trying to get the n-th element using your method.
phm
In that case, copy the UI dispatcher like this. Dispatcher UIdispatcher = Dispatcher.CurrentDispatcher; before you start your thread. Now in your thread instead of myListBox.Dispatcher use UIdispatcher.Invoke(...) Can you tell me how u called the Invoke method. I mean your code.
Veer
Use Invoke and not BeginInvoke. cast the d.Result into the desired type
Veer
A: 

Try this.
MylistBox is a ListBox

namespace TEST
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Thread th = new Thread(AccessList);
            th.Start(MylistBox);
        }

        void AccessList(Object O)
        {
            ListBox lBox = O as ListBox;
            for (int i = 0; i < lBox.Items.Count; i++)
            {
                MessageBox.Show(lBox.Items[i].ToString());
            }
        }
    }
}
Akshay