2015-12-03 3 views
4

Я наткнулся на какой-то код в профессиональной библиотеке и не уверен, что это чистый способ обработки вызовов потока через поток.Тематические события - это «чистый» способ?

Код приведен в приложении формы. звонки темы сделаны из класса, который сам начинает новый поток и получает сообщения:

private void Library_StatusChanged(object sender, AbstractTestCase.StatusChangedEventArgs e) 
{ 
    if (this.InvokeRequired) 
    { 
     this.lblProgress.Invoke((MethodInvoker)delegate() 
     { 
      lblProgress.Text = "Current state: " + e.Step; 
      lblProgress.Refresh(); 
     } 
     ); 

     this.pbProgess.Invoke((MethodInvoker)delegate() 
     { 
      pbProgess.Value = e.Percentage; 
      pbProgess.Refresh(); 
     }); 

     this.lstStatus.Invoke((MethodInvoker)delegate() 
     { 
      lstStatus.Items.Add(" " + e.Step); 
      lstStatus.Refresh(); 

     }); 

     this.Invoke((MethodInvoker)delegate() 
     { 
      this.Refresh(); 
     }); 
    } 
    else 
    { 
     lblProgress.Text = "Current state:" + e.Step; 
     lblProgress.Refresh(); 

     pbProgess.Value = e.Percentage; 
     pbProgess.Refresh(); 

     lstStatus.Items.Add(" " + e.Step); 
     lstStatus.Refresh(); 

     this.Refresh(); 
    } 

    Application.DoEvents(); 
} 

Является ли это «состояние искусства»? По-моему, это немного грязно ?!

+0

я обычно беру использование 'Application.DoEvents' как знак чего-то не так. И, вероятно, было бы более эффективно иметь только один «Invoke» вместо 4 отдельных. –

+0

Библиотека является однопоточной (помимо некоторых редких многопоточных частей), и, таким образом, пользовательский интерфейс замерзает. – AllDayPiano

+1

* "и, таким образом, пользовательский интерфейс зависает" * и 'Application.DoEvents' - это действительно дрянной способ бумаги над этой проблемой. –

ответ

5

Уровень техники: await. Если это невозможно, по крайней мере упростите код до одного вызова Invoke. Не нужно ссылаться на каждый элемент управления, просто вызывать в любом месте потока пользовательского интерфейса.

Проверка InvokeRequired не обязательна, так как вы должны знать о том, в какой теме событие поднято.

В любом случае дублирующая логика, такая как "Current state: " + e.Step, является действительно плохой идеей, и я бы отказался от этого в обзоре кода независимо от того, что.

Наличие Application.DoEvents - очень плохой знак. Наверное, недоразумение, потому что имеет смысл называть его в потоке пользовательского интерфейса, но почему Invoke, когда уже на потоке пользовательского интерфейса ?! Похоже на противоречие.

lstStatus.Refresh(); также является недоразумением, вероятно, суеверным. Элементы управления обновляются автоматически (если вы разрешаете обработку событий).

+0

Здравствуйте, usr, чтобы ответить на ваши вопросы: Invokation требуется, потому что событие может не быть запущено одним и тем же потоком. Есть что-то вроде асинхронного доступа COM-порта, который работает в другом потоке. Возможно также, что поток пользовательского интерфейса полностью занят, и, следовательно, DoEvent может перерисовать форму ?! То же самое для Control.Refresh() – AllDayPiano

+1

* 'lstStatus.Refresh();' также является недоразумением, вероятно, суеверным.* Cargo-культовое программирование. –

+0

@MattBurland да, парень сделал это один раз, и он скрыл замораживание потока пользовательского интерфейса, чтобы он теперь навсегда думает, что это решение. – usr

1

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

Используйте это простое решение:

private void Library_StatusChanged(object sender, AbstractTestCase.StatusChangedEventArgs e) 
{ 
    this.lblProgress.Invoke((MethodInvoker)delegate() 
    { 
     lblProgress.Text = "Current state: " + e.Step; 
    }); 

    this.pbProgess.Invoke((MethodInvoker)delegate() 
    { 
     pbProgess.Value = e.Percentage; 
    }); 

    this.lstStatus.Invoke((MethodInvoker)delegate() 
    { 
     lstStatus.Items.Add(" " + e.Step); 
    }); 
} 
+1

Это не код OPs. Это из библиотеки. Я предполагаю, что они не планируют переписывать библиотеку. Они просто задают вопрос о коде, с которым они столкнулись. –

+0

Jup Matt, ты прав. Мне не нравится lib, но бесплатно дешево, дешево хорошо, хорошо близко к совершенству и идеально, что ожидается: -/ – AllDayPiano

+0

Я попытался помочь. Его не о репутации ... –

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