The calling thread can not access this object because another thread has it

advertisements

I am using the following code.

public partial class SettingApp
{
    public SettingApp()
    {
        InitializeComponent();
        Parallel.Invoke(SetDataInTextBox);
    }

    private void SetDataInTextBox()
    {
        txtIncAns.Text = Properties.Settings.Default.IncludeAN;
        txtIncAuthor.Text = Properties.Settings.Default.IncludeAutt;
        txtIncQuo.Text = Properties.Settings.Default.IncludeQU;
        txtIncSpBegin.Text = Properties.Settings.Default.IncludeSP;
    }
}

The program gives the following error

The calling thread cannot access this object because a different

thread owns it.

Which is the right way

update :

Whether this is right :

   public partial class SettingApp
{
    private delegate void SetDataInTextBoxDelegate();
    public SettingApp()
    {
        InitializeComponent();

        txtIncAns.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new SetDataInTextBoxDelegate(SetDataInTextBox));
    }

     private void SetDataInTextBox()
    {
        txtIncAns.Text = Properties.Settings.Default.IncludeAN;
        txtIncAuthor.Text = Properties.Settings.Default.IncludeAutt;
        txtIncQuo.Text = Properties.Settings.Default.IncludeQU;
        txtIncSpBegin.Text = Properties.Settings.Default.IncludeSP;
    }
}


Only the UI thread can access UI elements, which I'm guessing is what those txt things are. Parallel.Invoke is in your case not the UI thread, so the exception is thrown when you try to access the .Text property on the controls.

You need to marshal the call across to the UI thread. In WinForms, controls have various ways to help you do this:

if (myControl.InvokeRequired)
{
    myControl.Invoke(...);
}
else
{
    myControl.Text = "something";
}

MSDN has an article with examples on it here (VS2010):

http://msdn.microsoft.com/en-us/library/757y83z4(v=VS.100).aspx

Update 1:

For WPF the model is similar, but includes the Dispatcher:

myControl.Dispatcher.Invoke(...);

Update 2: Of course, it looks like you don't even need to use multi-threaded code here. I would guess the overhead of using the multi-threaded portion is more than the code you eventually call. Simply remove the use of multiple threads from this section and set the properties directly:

    public SettingApp()
    {
        InitializeComponent();
        SetDataInTextBox();
    }

    private void SetDataInTextBox()
    {
        txtIncAns.Text = Properties.Settings.Default.IncludeAN;
        txtIncAuthor.Text = Properties.Settings.Default.IncludeAutt;
        txtIncQuo.Text = Properties.Settings.Default.IncludeQU;
        txtIncSpBegin.Text = Properties.Settings.Default.IncludeSP;
    }