Доступ к интерфейсу в потоке - PullRequest
9 голосов
/ 02 апреля 2009

Когда я пытаюсь изменить свойство пользовательского интерфейса (в частности, включить), мой поток выдает System.Threading.ThreadAbortException

Как получить доступ к пользовательскому интерфейсу в потоке.

Ответы [ 6 ]

19 голосов
/ 02 апреля 2009

Вы можете использовать BackgroundWorker, а затем изменить пользовательский интерфейс следующим образом:

control.Invoke((MethodInvoker)delegate {
    control.Enabled = true;
});
7 голосов
/ 02 апреля 2009

Если вы используете C # 3.5, очень просто использовать методы расширения и лямбды, чтобы предотвратить обновление пользовательского интерфейса из других потоков.

public static class FormExtensions
{
  public static void InvokeEx<T>(this T @this, Action<T> action) where T : Form
  {
    if (@this.InvokeRequired)
    {
      @this.Invoke(action, @this);
    }
    else
    {
      action(@this);
    }
  }
}

Так что теперь вы можете использовать InvokeEx в любой форме и иметь доступ к любым свойствам / полям, которые не являются частью Form.

this.InvokeEx(f => f.label1.Text = "Hello");
3 голосов
/ 02 апреля 2009

Полагаю, мы говорим здесь о WinForms? Вы должны иметь один поток, управляющий этим - поток, который создал рассматриваемый элемент управления. Если вы хотите сделать это из другого потока, который вы можете обнаружить с помощью Control.InvokeRequired, то вы должны использовать метод Control.Invoke, чтобы маршалировать это в правильный поток. Google это свойство и метод (соответственно) для некоторых общих шаблонов в этом.

1 голос
/ 02 апреля 2009
void button1_Click( object sender, EventArgs e ) {
    var thread = new Thread( ParalelMethod );
    thread.Start( "hello world" );
}
void ParalelMethod( object arg ) {
   if ( this.InvokeRequired ) {
       Action<object> dlg = ParalelMethod;
       this.Invoke( dlg, arg );
   }
   else {
       this.button1.Text = arg.ToString();
   }
}
1 голос
/ 02 апреля 2009

Используйте SynchronizationContext для перенаправления вызовов в поток пользовательского интерфейса, если вы хотите изменить пользовательский интерфейс, когда ваш поток не-пользовательский интерфейс все еще работает. В противном случае используйте BackgroundWorker.

1 голос
/ 02 апреля 2009

Как насчет использования класса BackgroundWorker в Win Form вместо ручной реализации и синхронизации?

...