Winforms я должен многопоточность или использовать таймер событий? - PullRequest
2 голосов
/ 05 марта 2009

В настоящее время у меня есть поток, который прослушивает данные из сети, а затем запускает правила для него. Затем я хочу передать данные в графический интерфейс. Я беспокоюсь о тупике в графическом интерфейсе. Я не могу понять, были ли мьютексы на стороне GUI. Я также использую c # и dotnet 3.5.

Что я придумал, так это 1) Использование таймера для создания события и вывода потока. Беспокоятся о производительности. 2) Используйте промежуточное событие для копирования данных в графический интерфейс. 3) Раскройте и выясните многопоточный способ использования GUI.

Как вы думаете, как лучше поступить?

Редактировать: вот решение, которое я использую. Я передаю измененный элемент и затем защищаю большой объект мьютексом. Я использую вспомогательную функцию для переключения потоков, используя InvokeRequired, а затем BeginInvoke с делегатом. Вытащил из чтения ответов и затем по ссылкам до достижения Threading в Windows Forms от Jon Skeet .

  delegate void UInt32ParameterDelegate(UInt32 n);

  public void UpdateLocation(UInt32 n)
  {
     if (InvokeRequired)
     {
        // We're not in the UI thread, so we need to call BeginInvoke
        BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
        return;
     }
     // Must be on the UI thread if we've got this far

     this.engine.location.UpdateBusy.WaitOne();
     // do the work in here

     this.engine.location.UpdateBusy.ReleaseMutex();

  }

Ответы [ 6 ]

3 голосов
/ 06 марта 2009

Синхронизация очень проста в Windows Forms. Вы можете вызвать Control.Invoke () в фоновом потоке. Поток будет останавливаться до тех пор, пока делегат не завершит работу в потоке пользовательского интерфейса. Синхронизация не требуется вообще.

Если проблема с остановкой потока, используйте Control.BeginInvoke (). Вы должны будете защитить объект (ы), который вы передаете делегату, с помощью блокировки, если поток может изменить их, пока он продолжает работать. Это редко имеет место в сценарии производитель-потребитель, поток может просто создавать новые объекты.

Убедитесь, что вы не вызываете () слишком часто. Делайте это чаще, чем примерно 1000 раз в секунду, и поток пользовательского интерфейса прекратит перекачивать сообщения Windows, которые останавливаются при обработке запросов на вызов. Так как вы пытаетесь угодить человеческим глазам, вызывать более 25 раз в секунду - это просто напрасная трата усилий. Объедините промежуточные результаты в объекте коллекции.

3 голосов
/ 05 марта 2009

Надеюсь, я правильно понимаю вашу проблему.

После того, как фоновый поток читает данные и делает все, что хочет, он должен использовать Invoke для вызова метода в потоке GUI. Этот метод обновит все, что должно быть обновлено в графическом интерфейсе.

2 голосов
/ 05 марта 2009

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

В вашей ситуации, я думаю, лучший подход - это выполнить фоновый поток для завершения операции чтения. Затем возьмите полученные данные и переместите их обратно в поток GUI с помощью метода SynchronizationContext Post или Send.

1 голос
/ 05 марта 2009

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

1 голос
/ 05 марта 2009

вы просто должны передать событие из вашего сетевого потока в ваш поток пользовательского интерфейса.

затем перекрестные потоки с помощью begininvoke, чтобы вы не получили исключение перекрестных потоков.

Нужна помощь в получении информации через поток пользовательского интерфейса и другой поток в C #

0 голосов
/ 05 марта 2009

Не проще ли просто выбросить делегата, который инициирует событие, которое информирует форму, чтобы обновить себя?

...