views:

431

answers:

3

hello all i have a problem whenever i Refresh the prograss bar i get the error The calling thread cannot access this object because a different thread owns it how can i remove it shashank

     backgroundWorker12 = new BackgroundWorker();
     timer1.Enabled = true;
      //cancel any async processes running for the background worker
     //backgroundWorker1.CancelAsync();
     backgroundWorker12.DoWork += (s, args) =>
     {

         BackgroundWorker worker2 = s as BackgroundWorker;
         worker2.WorkerReportsProgress = true;

         float percentageDone = 20f;
         //check if the user status and update the password in xml
         CheckUseridPwd();


         //call the function to sync the wall chart data

         //call the function to sync event relate data

         percentageDone = 100f;
         ValidateLogin2(txtUserID.Text.Trim(), txtPassword.Password.Trim(), -1); 
         worker2.ReportProgress((int)percentageDone);

     };`
+2  A: 

This bit looks like it's using UI controls from the wrong thread:

 ValidateLogin2(txtUserID.Text.Trim(), txtPassword.Password.Trim(), -1);

I suggest you capture the user and password in local string variables above the code which adds the event handler - you can use those captured variables within your delegate. That way everything should be on the right thread:

backgroundWorker12 = new BackgroundWorker();
timer1.Enabled = true;

string user = txtUserID.Text.Trim();
string password = txtPassword.Password.Trim();
backgroundWorker12.DoWork += (s, args) =>
{
    // ... same code as before up to here
    ValidateLogin2(user, password, -1); 
    worker2.ReportProgress((int)percentageDone);
};
Jon Skeet
its work great but when we bind the data with combobox as above in code it will give same error
Chunmun Tyagi
@SHASHANK: I'm afraid I don't know what you mean. Bind which data? As above in which code - mine or yours? Which thread are you trying to perform the binding in?
Jon Skeet
Sorry i write something wrongthanks
Chunmun Tyagi
A: 

See if you can use the RunWorkerCompleted event of the BackgroundWorker, since you're accessing the UI only after progress is 100% i.e. done.. Then you wouldn't have to worry about thread-affinity of WPF UI controls - since the event handler is invoked again on the right/ UI Thread.

The other option (if you need to access the UI controls before the work is complete) is to cache the object returned by Dispatcher.CurrentDispatcher on the UI Thread before the work starts and then use object.Invoke to marshal to the right thread from the thread pool thread that is executing your DoWork handler. See some code here.

Gishu
A: 

Have you tried invoking ValidateLogin2

you can either do it directly from your code shown, or in ValidateLogin2 check if the method itself requires invoking. If not, go ahead and validate, but if it does, then have it invoke itself

void ValidateLogin2(...)
{
  if (this.InvokeRequired)    
  {        
    //Invokes itself if required        
    BeginInvoke(new MethodInvoker(delegate(){ValidateLogin2(...);}));
  } 
  else 
  {
     //validate login here    
  }
}
Dawood Moazzem