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

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

     };`

Ответы [ 3 ]

5 голосов
/ 30 июня 2010

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

 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);
};
0 голосов
/ 30 июня 2010

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

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

void ValidateLogin2(...)
{
  if (this.InvokeRequired)    
  {        
    //Invokes itself if required        
    BeginInvoke(new MethodInvoker(delegate(){ValidateLogin2(...);}));
  } 
  else 
  {
     //validate login here    
  }
}
0 голосов
/ 30 июня 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...