Winforms выполняют код в отдельном потоке - PullRequest
4 голосов
/ 20 июля 2009

немного ювенильного вопроса ...

Я понимаю, что в приложении Winforms долго выполняющийся код должен выполняться в своем собственном потоке. Как это сделать, скажем, при нажатии кнопки?

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

Причина, по которой я выбрал этот метод, заключается в том, что (1) я хочу заблокировать любое взаимодействие пользователя с формой во время выполнения кода, и (2) предоставить пользователю указание о том, что обработка выполняется (I не знаю, как судить о том, сколько времени потребуется для выполнения определенного фрагмента кода, поэтому выбрал неопределенный gif-индикатор загрузки).

Кроме того, на тему выполнения кода в отдельных потоках ... не должно ли это применяться к любому коду или только конкретно к долговременному коду?

Буду очень признателен за любую помощь в этом вопросе! спасибо!

Ответы [ 3 ]

9 голосов
/ 20 июля 2009

Один из самых простых способов - использовать компонент BackgroundWorker. Добавьте в форму BackgroundWorker, добавьте обработчик события для события DoWork и оттуда вызовите долгосрочную функцию. Вы можете запустить его в обработчике событий нажатия кнопки, вызвав метод RunWorkerAsync компонента BackgroundWorker.

Чтобы узнать, когда операция готова, настройте обработчик для события RunWorkerCompleted.

private void Button_Click(object sender, EventArgs e)
{
    myBackgroundWorker.RunWorkerAsync();
}

private void myBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // long-running operation here; will execute on separate thread
}

private void myBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // operation is ready
}
4 голосов
/ 20 июля 2009

Я отвечу на вторую половину вашего вопроса (как Фредрик уже объяснил BackgroundWorker):

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

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

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

2 голосов
/ 20 июля 2009

Я попытаюсь ответить на вторую часть вашего вопроса, основываясь на своем собственном опыте. Обычно вы будете использовать потоки только в одном из трех случаев:

  • Об операциях, которые будут блокироваться в течение заметных периодов времени при системных вызовах (File / Socket IO и т. Д.)

  • В длительных операциях, когда потеря скорости отклика интерфейса нежелательна.

  • При множественных длительных операциях, где желательно использование многоядерной среды.

Как говорит Эндрю Шепард, существуют накладные расходы на использование потоков. Потоки сильно усложняют вещи. Никогда не нанизывать ради нити.

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