locked
Error: The calling thread cannot access the object because different thread owns it

    Question

  • I have declared a listbox as follows:

    internal System.Windows.Controls.ListBox ListBox;

    Then I have initialized a workflow:

    public void InitializeGetMyPhotosNotInSetWorkflow(string extras, string extrasValue, string perPage, string perPageValue, string page, string PageValue)

    {

    parameters.Add(extras, extrasValue);

    parameters.Add(perPage, perPageValue);

    parameters.Add(page, PageValue);

    try

    {

    if ((this.workflowRuntime = new WorkflowRuntime()) == null)

    {

    throw new System.Exception("There was a problem creating the workflow runtime.\nThe Application will now exit.");

    }

    else

    {

    // Add the External Data Exchange Service

    ExternalDataExchangeService dataService =

    new ExternalDataExchangeService();

    // Add CallFlickrMethods to the dataService

    this.workflowRuntime.AddService(dataService);

    dataService.AddService(new FlickrAPI.CallFlickrMethods());

    //Add GetFlickrKey to the dataService

    dataService.AddService(new FlickrAPI.FlickrKeys());

    }

    }

    catch (System.Exception ex)

    {

    System.Windows.MessageBox.Show(ex.Message.ToString());

    }

    this.instance = workflowRuntime.CreateWorkflow(typeof(FlickrActivityLibrary.GetMyPhotosNotInSet), parameters);

     

    this.workflowRuntime.WorkflowCompleted += delegate(object s, WorkflowCompletedEventArgs ex)

    {

    this.ds1 = ex.OutputParameters["dataSet"] as DataSet;

    UpdateListBox(ds1);

    parameters.Clear();

    waitHandle.Set();

    };

    workflowRuntime.WorkflowTerminated += delegate(object s, WorkflowTerminatedEventArgs ex)

    {

    Console.WriteLine(ex.Exception.Message);

    parameters.Clear();

    waitHandle.Set();

    };

    }

    Everything works fine till the UpdateListBox method is called, which throws the exception (The calling thread cannot access the object because different thread owns it)

    the code for the updateListBox method is:

    void UpdateListBox(DataSet ds)

    {

    pc = new PhotoAlbum.PhotosCollection();

    pc.ds = ds;

    pc.GetData();

    ListBox.ItemsSource = pc.Photos;

    }

    Any ideas why I get the exception (The calling thread cannot access the object because different thread owns it) and how to solve the problem?

    Thursday, September 14, 2006 10:26 PM

Answers

  • If you haven't found the answer to your problem yet try this blog entry.
    Monday, September 25, 2006 3:43 PM

All replies

  • You need to change your UpdateListBox method to the following:

     

    private delegate void UpdateListBoxDelegate(DataSet ds);

     

    void UpdateListBox(DataSet ds)

    {

        if (ListBox.InvokeRequired)

        {

            UpdateListBoxDelegate updateListBox = new UpdateListBoxDelegate(this.UpdateListBox);

     

            // Create the array of parameters for this method

            object[] args = new object[1] { ds };

     

            // Invoke this method on the UI thread

            this.ListBox.Invoke(updateListBoxItem, args);

        }

        else

        {

      pc = new PhotoAlbum.PhotosCollection();

      pc.ds = ds;

      pc.GetData();

      ListBox.ItemsSource = pc.Photos;

        }

    }

    Thursday, September 14, 2006 11:24 PM
  • Ok, would somebody be so kind to explain the above,....

    1. What does the InvokeRequired do?
    2. why is the delegate used in the method?
    3.why is the listbox.invoke method used?
    4. In which cases the else branch will execute?

    Friday, September 15, 2006 7:41 AM
  • Also, when using the above code I get two errors, that the ListBox.invokeRequired and ListBox.Invoke do not exist. I forgot to mention that the listbox is a WPF listbox, not a windows forms one...

    Any there maybe some equivalents (in WPF listobx ) to windows forms listbox?

    Any ideas how to solve this problem ?

    Thanks,
    M. Vuksanovic.

    Friday, September 15, 2006 7:59 AM
  • I have also tried using the following code, but the application hangs when it comes to the line of code in red...

    public void BindListBox(DataSet data)

    {

    pc = new FlickrAPI.PhotosCollection();

    pc.ds = data;

    pc.GetData();

    this.ListBox.ItemsSource = pc.Photos;

    }

    void UpdateListBox(DataSet ds)

    {

    UpdateListBoxDelegate updateListBox = new UpdateListBoxDelegate(this.BindListBox);

    // Create the array of parameters for this method

    object[] args = new object[1] { ds };

    // Invoke this method on the UI thread

    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, updateListBox, args);

    //this.ListBox.Invoke(updateListBox, args);

    }

    Why does this happen? Shouldn't the red line of code call the BindListbox(...) method on the UI thread?

    Friday, September 15, 2006 8:34 AM
  • Sorry, I should have explained what the code was doing and why it is needed.  I assumed that it was a winform app since you didn’t mention WPF and this code will not work there.  ListBox.InvokeRequired checks to see if the control can be modified on the current thread.  A delegate is used because if InvokeRequired == true then you need call Invoke, which takes a delegate and an object array containing the parameters for the delegate.  When the UpdateListBox is called the first time from the workflow thread because invoke is required the delegate is used to call back into the same method on the UI thread.  This time invoke won’t be required and the ItemsSource can be updated.

     

    I have not worked with WPF enough to know why your new code does not work and would suggest posting your question to their forum here.

    Saturday, September 16, 2006 4:28 PM
  • If you haven't found the answer to your problem yet try this blog entry.
    Monday, September 25, 2006 3:43 PM