2010-11-30 61 views
13

HI all。 我有一个运行Worker类实例的BackgroundWorker对象数组。当我调用Worker类时,对象实例就是这样,然后用完代码(循环结束)。我能听RunWorkerCompleted()事件,但是当它调用,我已经建立了委托我需要知道哪些我工人的对象刚刚完成。如何设置在RunWorkerCompletedEventArgs对象UserState?

我看到这使我委托RunWorkerCompletedEventArgs一个UserState属性,但我不知道如何,因为它是在完成设置这在我的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对象完成了循环在其开始()方法,我该怎么办,以填补RunWorkerCompleteEventArgs对象“E”的userState属性,传递给我的WorkerFinished方法()?

感谢

回答

12

Start方法对Worker类可以设置DoWorkEventArgs参数的Result财产。这里有一个例子:

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()) 
        }); 
    } 
} 
+0

感谢菲利普,该诀窍。关于总是检查e.Cancelled的评论是关键。我实际上是通过调用BackgroundWorker对象的CancelAsync()方法来停止我的工作线程。这导致RunWorkercompletedEventArgs Result属性没有我的原始对象。我重构了通过在工作对象上设置一个属性来停止工作(以线程安全的方式!),并在工人的代码循环中检查它。如果我看到它的信号,我只是退出循环,瞧,RunWorkercompletedEventArgs参数在e.Result中有我的对象。 – sisdog 2010-11-30 08:57:44

1

UserState件事就是BackgroundWorker一个已知的bug:

http://www.pluralsight-training.net/community/blogs/mike/archive/2005/10/21/15783.aspx(存档。组织链接…原来的链接是死的)

我已经在过去做什么时,我已经在你的情况是要么使用RunWorkerCompletedEventArgs.Result(菲利普建议),或者,如果可能的话,有我的工人从BackgroundWorker(派生那么我可以,因为我想添加尽可能多的额外的状态,并获得全职工作为发件人参数由BackgroundWorker引发的事件,同时仍然能够使用Result达到预期目的)。