Основное использование BackgroundWorker с параметрами - PullRequest
20 голосов
/ 26 апреля 2011

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

object.Method(paramObj, paramObj2);

Все три из этих объектов я создал.Теперь из первоначальных примеров, которые я видел, вы можете передать объект в метод DoWork фонового работника.Но как мне поступить так, если мне нужно передать дополнительные параметры этому объекту, как я делаю здесь?Я мог бы обернуть это в один объект и покончить с этим, но я подумал, что было бы разумно получить чей-то вклад в это.

Ответы [ 4 ]

54 голосов
/ 26 апреля 2011

Вы можете передать любой объект в аргумент объекта вызова RunWorkerAsync, а затем получить аргументы из события DoWork.Вы также можете передать аргументы из события DoWork в событие RunWorkerCompleted, используя переменную Result в DoWorkEventArgs.

    public Form1()
    {
        InitializeComponent();

        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

        object paramObj = 1;
        object paramObj2 = 2;

        // The parameters you want to pass to the do work event of the background worker.
        object[] parameters = new object [] { paramObj, paramObj2 };

        // This runs the event on new background worker thread.
        worker.RunWorkerAsync(parameters);
    }

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        object[] parameters = e.Argument as object[];

        // do something.

        e.Result = true;
    }

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        object result = e.Result;

        // Handle what to do when complete.                        
    }
10 голосов
/ 26 апреля 2011

Самым простым способом, который мне приходит в голову, было бы создание класса со свойством для каждого имеющегося у вас объекта и его передача.

public class MyWorkerContext
{
   public Object1 Worker;
   public Object2 Parameter1;
   public Object2 Parameter2;
}

, тогда в DoWork вы просто делаете что-то вроде:

MyWorkerContext context = e.Argument as MyWorkerContext;

context.Worker.Method(context.Parameter1, context.Parameter2);
6 голосов
/ 26 апреля 2011

Вы можете захватить их в лямбду для DoWork:

bgw.DoWork += (sender, e) => object.Method(paramObj, paramObj2) ;

e.Argument (то есть значение состояния или объект, переданный BackgroundWorker.RunWorkerAsync()) может быть 1 из 3, но оно имеет тип System.Object и требует бокса. Передача всех параметров непосредственно в лямбду дает вам полную безопасность типов для всех параметров без необходимости в боксе или кастинге.

1 голос
/ 26 апреля 2011

Вы можете передать объект в метод BackgroundWorker.RunWorkerAsync ().Вы должны обернуть ваши два paramObjs в один объект (вы можете использовать массив, кортеж или другой составной класс, который вы напишите) и передать его в качестве аргумента в RunWorkerAsync ().

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

Для полного примера посмотрите на MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx

...