Как установить UserState в объекте RunWorkerCompletedEventArgs? - PullRequest
13 голосов
/ 30 ноября 2010

Привет всем.У меня есть массив объектов BackgroundWorker, в которых выполняются экземпляры класса Worker.Когда я вызываю класс Worker, экземпляр объекта делает свое дело, а затем исчерпывает код (цикл завершается).Я могу слушать событие RunWorkerCompleted (), но когда он вызывает делегата, которого я настроил, мне нужно знать, какой из моих объектов Worker только что завершен.

Я вижу свойство UserState в RunWorkerCompletedEventArgs, которое приходит к моему делегату, но я понятия не имею, как установить его в моем объекте Worker по мере его завершения.

Есть идеи?

фрагмент из моего класса WorkManager.cs

public Worker AddWorker()
{
    Worker w = new Worker();

    _workers.Add(w.WorkerID,w);

    BackgroundWorker bg = new BackgroundWorker();
    _bgworkers.Add(bg);

    bg.DoWork += w.Start;
    bg.WorkerReportsProgress = true;
    bg.WorkerSupportsCancellation = true;
    bg.ProgressChanged += ProcessWorkerMessage;
    bg.RunWorkerCompleted += WorkerFinished;


    w.WorkManager = this;
    w.BackgroundWorker = bg;

    bg.RunWorkerAsync(w);


    return w;

}


public void WorkerFinished(object sender, RunWorkerCompletedEventArgs e)
{
    if (_onManagerEvent != null)
        _onManagerEvent(new ManagerEvent { EventDate = DateTime.Now, Message = "Worker ??? successfully ended." });
}

Итак, когда мой объект Worker завершает цикл в своем методе Start (), что мне нужно сделать, чтобы заполнить свойство userState объекта RunWorkerCompleteEventArgs"e", которое передается моему методу WorkerFinished ()?

Спасибо

Ответы [ 2 ]

13 голосов
/ 30 ноября 2010

Ваш метод Start в классе Worker может установить свойство Result аргумента DoWorkEventArgs.Вот пример:

void Start(object sender, DoWorkEventArgs e)
{
   //Do your loop and other work.
   e.Result = this;
}

Затем в обработчике события финиша вы можете получить e.Result:

public void WorkerFinished(object sender, RunWorkerCompletedEventArgs e)
{
    //You should always check e.Cancelled and e.Error before checking e.Result!
    // ... even though I'm skipping that here

    Worker w = e.Result as Worker;
    if( w != null)
    {
        if (_onManagerEvent != null)
            _onManagerEvent(new ManagerEvent 
                    { 
                      EventDate = DateTime.Now, 
                      Message = String.Format("Worker {0} successfully ended."
                                              , w.ToString()) 
                    });
    }
}
3 голосов
/ 30 ноября 2010

Эта вещь UserState является известной ошибкой в ​​BackgroundWorker:

http://www.pluralsight -training.net / community / blogs / mike / archive / 2005/10/21/15783.aspx (ссылка на archive.org… исходная ссылка не работает)

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

...