Как заставить BackgroundWorker возвращать объект - PullRequest
52 голосов
/ 02 июня 2009

Мне нужно заставить RunWorkerAsync() вернуть List<FileInfo>. Как я могу вернуть объект из фонового рабочего?

Ответы [ 6 ]

91 голосов
/ 02 июня 2009

В вашем DoWork обработчике события для BackgroundWorker (где происходит фоновая работа) есть аргумент DoWorkEventArgs. Этот объект имеет объект публичного свойства Result. Когда ваш работник сгенерирует свой результат (в вашем случае, List<FileInfo>), установите e.Result на это и верните.

Теперь, когда ваш BackgroundWorker завершил свою задачу, он запускает событие RunWorkerCompleted, в котором в качестве аргумента используется объект RunWorkerCompletedEventArgs. RunWorkerCompletedEventArgs.Result будет содержать результат от вашего BackgroundWorker.

пример:

private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    int result = 2+2;
    e.Result = result;
}

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    int result = (int)e.Result;
    MessageBox.Show("Result received: " + result.ToString());
}
19 голосов
/ 02 июня 2009

Я предполагаю, что вы не хотите блокировать и ждать в RunWorkerAsync () результатов (если бы вы это сделали, не было бы никакой причины запускать async!

Если вы хотите получать уведомление о завершении фонового процесса, подключите событие RunWorkerCompleted. Если вы хотите вернуть какое-либо состояние, верните его в элемент Result аргументов событий DoWork.

РЕДАКТИРОВАТЬ: я отправил преждевременно - закончил мой пример кода

Пример:



    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
      // do your thing
      ....
      // return results
      e.Result = theResultObject;
    }

    // now get your results
    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      MyResultObject result = (MyResultObject)e.Result;
      // process your result...
    }


1 голос
/ 02 июня 2009

Ваш поток может вызвать событие с объектом в качестве аргумента:

ThreadFinishedEvent(this, new ThreadEventArgs(object));

где:

public class ThreadEventArgs : EventArgs
{
    public ThreadEventArgs(object object)
    {
        Object = object
    }

    public object Object
    {
        get; private set;
    }
}
1 голос
/ 02 июня 2009

RunWorkerAsync() запускает процесс асинхронно и будет возвращать и продолжать выполнение кода до фактического завершения процесса. Если вы хотите получить результат BackgroundWorker, вам нужно создать переменную экземпляра для хранения этого значения и проверить его после завершения BackgroundWorker.

Если вы хотите дождаться окончания работы, вам не нужно BackgroundWorker.

0 голосов
/ 02 июня 2009

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

Вы можете проверить новый PFX, который имеет некоторую функцию параллелизма, которая может возвращать значения.

Например, есть функция Parallel.ForEach (), которая имеет перегрузку, которая может возвращать значение.

проверьте это для получения дополнительной информации

http://msdn.microsoft.com/en-us/magazine/cc817396.aspx

0 голосов
/ 02 июня 2009

В зависимости от вашей модели, вы либо хотите, чтобы ваш рабочий поток перезванивал своему создателю (или какому-либо другому процессу), когда он завершил свою работу, либо вам приходится периодически опрашивать рабочий поток, чтобы увидеть, завершен ли он. и, если это так, получить результат.

Идея ожидания возвращения рабочего потока своим результатом подрывает преимущества многопоточности.

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