C # Windows формы - вопрос о кросс-потоке событий - PullRequest
0 голосов
/ 24 июня 2019

Допустим, я создал имя класса myClass, и у этого класса есть свойство myValue с любым типом, не имеет значения, например:

class myClass
{
   public delegate void OverTheLimitDlg(int arg);
   public event OverTheLimitDlg OverTheLimit;
   public myClass()
   {
       myValue = 0;
   }
   private int myvalue = 0;
   public int myValue 
   {
      get { return myvalue;}
      set 
      {
         myValue = value;
         if(value > 5)
            OvertheLimit(value);
      }
    }
}

У меня есть метка winforms с именем myLabel в форме, и я создаю объект с типом myClass в событии Form Load, подписываюсь на его событие OverTheLimit и запускаю backgroundworker:

myClass myObj; 

private void Form_Load(object sender, EventArgs e)
{
   myObj = new myClass();
   myObj.OverTheLimit += SubsMethod;
   backgroundworker.RunWorkerAsync();
}

private void backgroundworker_DoWork(...)
{
   myObj.myValue = 10;
   //Some expressions.
}

private void SubsMethod(int someInt)
{
   myLabel.Text = "Oh it's over the limit!";
}

Резюме: я создаю класс, для которого объект, экземпляр которого создан, может инициировать событие. Я заставляю объект запускать событие в потоке, и он запускает метод, который влияет на объект GUI, объект, созданный и выполняющийся в другом потоке. Я никогда не пробовал. Что произойдет в такой ситуации? Это вызывает ошибку? Спасибо.

1 Ответ

1 голос
/ 24 июня 2019

Что произойдет в такой ситуации?

myLabel.Text = "Oh it's over the limit!";

Эта строка выдаст InvalidOperationException, когда попытается отредактировать myLabel из потока BackgroundWorker. Элементы управления WinForms должны быть изменены из потока, в котором они созданы, поэтому существует Control.InvokeRequired.

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

private void SubsMethod(int someInt)
{
    if (myLabel.InvokeRequired) {
        myLabel.Invoke(new MethodInvoker(()=>SubsMethod(someInt)));
        return;
    }
    myLabel.Text = "Oh it's over the limit!";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...