Как установить UserState в объекте RunWorkerCompletedEventArgs?

HI все. У меня есть массив объектов 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 объекта "e" RunWorkerCompleteEventArgs, которое передается моему методу WorkerFinished()?

Спасибо

Ответы

Ответ 1

Ваш метод 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()) 
                    });
    }
}

Ответ 2

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

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

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