Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток

У меня проблема, когда я обновляю панель prograss. Я получаю сообщение об ошибке. Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток как я могу удалить его 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);

     };`

Ответ 1

Этот бит выглядит с использованием элементов управления пользовательского интерфейса из неправильного потока:

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

Я предлагаю вам захватить пользователя и пароль в локальных строковых переменных выше кода, который добавляет обработчик событий - вы можете использовать эти захваченные переменные в своем делетете. Таким образом, все должно быть на правильном пути:

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);
};

Ответ 2

Посмотрите, можете ли вы использовать RunWorkerCompleted событие BackgroundWorker, поскольку вы получаете доступ к пользовательскому интерфейсу только после того, как прогресс достигнут на 100%, т.е... Тогда вам не придется беспокоиться о привязке потоков к элементам управления WPF UI, поскольку обработчик событий снова запускается в правом/UI-потоке.

Другой вариант (если вам нужно получить доступ к элементам пользовательского интерфейса до завершения работы), необходимо кэшировать объект  возвращаемый Dispatcher.CurrentDispatcher в потоке пользовательского интерфейса до начала работы, а затем использовать object.Invoke для маршалирования в нужный поток из потока потока потока, который выполняет ваш DoWork-обработчик. См. некоторый код здесь.

Ответ 3

Вы пытались вызвать ValidateLogin2

вы можете либо сделать это непосредственно из показанного вами кода, либо в ValidateLogin2 проверить, требует ли сам метод. Если нет, продолжайте и проверяйте, но если это так, то пусть он вызывает себя

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