The Problem :
- You are writing a windows application
- You make an asynchronous webservice call (or you launch a background worker thread to get some data)
- m_WebService1.FuncAsync() ‘If you are using VB.Net you probably have a member variable declared for the webservice and you are calling the MethodXXXAsync() function generated by Visual Studio when you added the WebReference.
- In your m_WebService1_MethodXXCompleted() event handler, you try to update the User Interface (eg. txtBox.text = value)
- At this point the screen blows up and you get the dreaded error :
Cross-thread operation not valid: Control ‘Form1′ accessed from a thread other than the thread it was created on
The Reason:
- If you are from the old COM/COM+ Days, you must remember that an STA (Single Threaded Apartment) can only be accessed by the thread that originally created it. All the controls on the form are created by the main thread of the application, so only the main thread can update it. When your asynch webservice call returns it is calling the MethodXXCompleted() event handler in the context of a different thread. This thread is not allowed to touch any controls on the form
The Solution :
- From the Asynch event handler, you need to invoke the function which will update the UI from the context of the original thread.

- Say, the function which will update the UI is called Private Sub UpdateApps(), you need to declare a delegate for this function. Later we invoke this delegate (see step2 to do the actual work). You cannot call this function directly because it will still happen in the context of the second thread and you will get the same error.

That should take care of the problem. J
Great…. Actually i had also the same problem..and I also Used delegate to fix it..
Your solution was solved my problem also. Thanks.
nice soln.
Great solution. Simple and useful Great job
Hi Nishant,
I am getting same error “Cross-thread operation not valid: Control ‘Form1′ accessed from a thread other than the thread it was created on” first time i open an application.
I have created thread which opens splash screen form, then i open login form from splash screen form
Following is my code snippet:
Form form;
delegate void ShowFormDelegate();
void ShowDialog(Form f)
{
form = f;
//clsLogger.log(f.Handle.ToString());
//clsLogger.log(f.IsHandleCreated.ToString());
Form splash = CampaignRoleEditor.Program.objfrmSplash;
//clsLogger.log(”Invoke Required” + splash.InvokeRequired.ToString());
clsLogger.log(”Invoke Required f” + f.InvokeRequired.ToString());
ShowFormDelegate d = new ShowFormDelegate(ShowDialogDelegate);
//if (f.InvokeRequired == true)
splash.Invoke(d);
}
void ShowDialogDelegate()
{
form.ShowDialog();
}
I m calling function from following
Form objfrmLogin = new frmLogin();
ShowDialog(objfrmLogin);
Pl let me know , if u find any solution.
Thanks,
Gaurav
I’d like to add my code to this article. It took me a while to figure out so I thought it was worth sharing. This sample allows you to update the text on a control, and returns the previous text, so it gives you an example where the delegate function accepts and returns a parameter. Hope it helps!
A Sample to write text to a Status Bar Panel, and return the original text.
Old Code:
public string SetStatusPanel( string strStatus, bool bError )
{
try
{
strOldStatus = statusBarPanelStatus.Text;
statusBarPanelStatus.Text = strStatus;
}
catch (Exception Ex)
{
Debug.WriteLine(Ex.Message);
}
return strOldStatus;
}
New Code:
public delegate string StatusPanelDelegate(string strStatus);
public string SetStatusPanel( string strStatus, bool bError )
{
if (this.statusBar.InvokeRequired)
{
try
{
strOldStatus = Convert.ToString(this.statusBar.Invoke(new StatusPanelDelegate(StatusPanelDelegateSetText), strStatus));
}
catch (System.Exception e)
{
Debug.WriteLine(e.Message);
}
}
else
{
try
{
strOldStatus = statusBarPanelStatus.Text;
statusBarPanelStatus.Text = strStatus;
}
catch (Exception Ex)
{
Debug.WriteLine(Ex.Message);
}
}
return strOldStatus;
}
private string StatusPanelDelegateSetText(string strStatus)
{
string strOldStatus = statusBarPanelStatus.Text;
statusBarPanelStatus.Text = strStatus;
return strOldStatus;
}
Hello. It is test.
I am here at a forum newcomer. Until I read and deal with the forum.
Let’s learn!
Nothing seems to be easier than seeing someone whom you can help but not helping.
I suggest we start giving it a try. Give love to the ones that need it.
God will appreciate it.
Nice Solution.
I am new in multithreading. Please give me detail information about multithreading.
thanks it worked for me ..
Hi, i’m doing an asynchronous webservice call and I get the Cross-thread operation not valid: “Control ‘Form1′ accessed …” error. I’ve spend all day looking for solution but… hey, it’s your same problem…
Trying your solution…
WORKS!!!!!!!
I own u a beer!