2013-08-02 2 views
-1

У меня есть этот метод:Как включить или отключить кнопку в событии DoWork рабочего стола?

private void CreateDriversList() 
     { 
      try 
      { 
       StreamWriter w = new StreamWriter(contentDirectory + "\\" + "Drivers.txt"); 
       w.WriteLine("Module Name   Display Name   " + "    " + "          Driver Type"); 
       w.WriteLine("===========   ============ " + "    " + "             ==========="); 
       System.Management.SelectQuery query = new System.Management.SelectQuery("Win32_SystemDriver"); 
       System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query); 
       foreach (System.Management.ManagementObject ManageObject in searcher.Get()) 
       { 
        w.WriteLine("{0,-22} {1,-75} {2}", ManageObject["Namedfgfdg"], ManageObject["DisplayName"], ManageObject["ServiceType"]); 
        driversListNumbers += 1; 
       } 
       w.Close(); 
       Logger.Write("***** Drivers Text File Have Been Created *****"); 
      } 
      catch(Exception err) 
      { 
       Logger.Write("There was an exception" + Environment.NewLine + err); 
       SendEmail.Enabled = true; 
      } 

     } 

Этот метод вызывается из события DoWork и при запуске программы им получить исключение:

операции кросс-нить не действует: Control «SendEmail» доступны из нить, отличная от нити, была создана на

System.InvalidOperationException was unhandled by user code 
    HResult=-2146233079 
    Message=Cross-thread operation not valid: Control 'SendEmail' accessed from a thread other than the thread it was created on. 
    Source=System.Windows.Forms 
    StackTrace: 
     at System.Windows.Forms.Control.get_Handle() 
     at System.Windows.Forms.Control.OnEnabledChanged(EventArgs e) 
     at System.Windows.Forms.ButtonBase.OnEnabledChanged(EventArgs e) 
     at System.Windows.Forms.Control.set_Enabled(Boolean value) 
     at Diagnostic_Tool_Blue_Screen.Form1.CreateDriversList() in d:\C-Sharp\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Form1.cs:line 135 
     at Diagnostic_Tool_Blue_Screen.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in d:\C-Sharp\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Form1.cs:line 177 
     at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) 
     at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument) 
    InnerException: 
+0

Использовать Диспетчер для него, но использовать Google в следующий раз, легко найти – wudzik

+0

Это приложение WPF или Windows Forms? Из-за ошибки это выглядит как Windows Forms, поэтому вам нужно будет использовать старую проверку InvokeRequired или использовать прогресс отчета BackgroundWork. http://msdn.microsoft.com/en-us/library/ka89zff4.aspx – owen79

ответ

3

Рабочие нити никогда не должны касаться пользовательского интерфейса. Используйте BeginInvoke вместо:

SendEmail.BeginInvoke((Action)delegate() { SendEmail.Enabled = true; }); 
+0

rodrigo попробовал ваше решение, но im получил сообщение об ошибке: Ошибка Невозможно преобразовать анонимный метод, чтобы ввести 'System.Delegate', потому что он не является типом делегирования – DanielVest

+0

@DanielVest 'SendEmail.BeginInvoke (новое действие (() => {SendEmail.Enabled = true;}));' –

+0

@DanielVest: Да, дело в том, что 'BeginInvoke' берет' System. Делегат', и, как ни странно, это не тип делегата. Таким образом, либо вы используете уже существующий тип делегата (например, «Действие», см. Мой обновленный ответ или комментарий @KingKing), либо вы создаете свой собственный. – rodrigo

0

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

Смежные вопросы