Модель потоков .NET и приложение. DoEvents против Thread.Sleep - PullRequest
6 голосов
/ 28 апреля 2009

У нас есть настольное приложение, которое выполняет довольно строгий набор вычислений в фоновом потоке. Части этого вычисления выполняются в неуправляемой библиотеке, к которой мы получаем доступ через взаимодействие. Мы обнаруживаем, что когда мы запускаем вычисления, поток пользовательского интерфейса перестает отвечать на запросы во время вычислений. У нас сложилось впечатление, что фреймворк будет обрабатывать переключение потоков, чтобы пользовательский интерфейс продолжал реагировать, но это не так. Мы обнаружили, что мы можем вставить Thread.Sleep (0) или Application.DoEvents (), чтобы позволить пользовательскому интерфейсу реагировать. Это имеет побочный эффект замедления расчета. Кроме того, на части вычислений, выполняемых неуправляемым кодом, может потребоваться до 30 секунд, и в течение этого времени приложение всегда не отвечает. Весь расчет может занять от двух до пяти минут.

Это приводит к следующим вопросам:

  • Что такое модель потоков .NET Framework с точки зрения пользовательского интерфейса и взаимодействия?
  • Мы ошибаемся, полагая, что среда должна обрабатывать переключение потоков между фоновым потоком и потоками пользовательского интерфейса?
  • В чем разница между использованием Thread.Sleep и Application.DoEvents в этой ситуации, и один из них предпочтительнее другого?

Ответы [ 3 ]

2 голосов
/ 04 апреля 2012

Ваш лучший выбор - создать свой собственный Thread. DoEvents и Thread.Sleep(0) блокируют вычисления, замедляя их. Вы можете заключить вызовы DLL в делегат ThreadStart или в делегат ParameterizedThreadStart и использовать имя делегата в качестве параметра при создании экземпляра Thread. Оттуда все, что вам нужно сделать, это вызвать метод Start Thread.

2 голосов
/ 28 апреля 2009

Вы можете понизить приоритет фонового потока, так что ОС будет вытеснять его больше. Если у вас есть знание предметной области, которое заставляет вас хотеть контролировать, когда оно прервано, вы можете использовать Thread.Sleep (0), который отменяет ваш временной интервал, если другой поток ожидает.

Application.DoEvents перекачивает очередь сообщений Windows. Это заставит ваше приложение реагировать на такие события, как нажатие клавиш или изменение размеров окна. Thread.Sleep приведет к прерыванию вашего потока (или, может быть, нет, в случае Thread.Sleep (0)).

Также читайте Threading в C #

0 голосов
/ 15 июля 2010

Правильный способ сделать это - использовать обратные вызовы. См. Модель Silverlight с использованием асинхронных методов (например, для получения данных веб-службы). Я знаю, что на этот вопрос "дан ответ", но ответ не идеален ИМХО.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...