Решить сквозное исключение в WinForms - PullRequest
8 голосов
/ 03 мая 2011

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

"Операция с несколькими потоками недопустима: доступ к элементу управления" выполняется из потока, отличного от потока, в котором он был создан. "

Как я могу решить эту ошибку?

Ответы [ 6 ]

11 голосов
/ 03 мая 2011

При выполнении вызовов метода для элемента управления, если вызывающая сторона находится в потоке, отличном от того, в котором был создан элемент управления, необходимо вызвать с помощью Control.Invoke . Вот пример кода:

// you can define a delegate with the signature you want
public delegate void UpdateControlsDelegate();

public void SomeMethod()
{
    //this method is executed by the background worker
    InvokeUpdateControls();
}

public void InvokeUpdateControls()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new UpdateControlsDelegate(UpdateControls));
    }
    else
    {
        UpdateControls();
    }
}

private void UpdateControls()
{
    // update your controls here
}

Надеюсь, это поможет.

4 голосов
/ 03 мая 2011

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

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

2 голосов
/ 03 мая 2011

Вам необходимо проверить, требуется ли Invoke для элемента управления, который вы пытаетесь обновить.Как то так:

Action<Control, string> setterCallback = (toSet, text) => toSet.Text = text;

void SetControlText(Control toSet, string text) {
  if (this.InvokeRequired) {
    this.Invoke(setterCallback, toSet, text);
  }
  else {
    setterCallback(toSet, text);
  }
}
1 голос
/ 03 мая 2011

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

    public delegate void InvocationDelegate();

    public void DoGuiStuff(){
      if (someControl.InvokeRequired){
        someControl.Invoke(InvocationDelegate(DoGuiStuff));
        return;  
      }

      //GUI manipulation here
    }

Использование этого паттерна - если при вызове метода вы находитесь в правильном потоке, он не вызывает сам себя, но если вы находитесь в другом потоке, он будет вызывать сам себя, а затем возвращаться (поэтому логика манипуляции GUI только когда-либо называется один раз в любом случае).

0 голосов
/ 10 мая 2016

Изменения пользовательского интерфейса могут быть сделаны с помощью методов Control.Invoke (), это исключение кросс-потока может быть решено с использованием приведенного ниже фрагмента кода.

void UpdateWorker()
{
   //Here ddUser is the user control
   //Action to be performed should be called within { } as like below code
   if (this.ddUser.InvokeRequired)
      ddUser.Invoke(new MethodInvoker(() => { ddUser.Size = new Size(100, 100); }));
}
0 голосов
/ 03 мая 2011

Обновлено из Invoke для начала Invoke

// you can define a delegate with the signature you want
public delegate void UpdateControlsDelegate();

public void SomeMethod()
{
    //this method is executed by the background worker
    InvokeUpdateControls();
}

public void InvokeUpdateControls()
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new UpdateControlsDelegate(UpdateControls));
    }
    else
    {
        UpdateControls();
    }
}

private void UpdateControls()
{
    // update your controls here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...