2010-11-30 18 views
13

HI全て。 Workerクラスのインスタンスを実行するBackgroundWorkerオブジェクトの配列があります。 Workerクラスを呼び出すと、オブジェクトインスタンスはそれを行い、コードがなくなります(ループが終了します)。私はRunWorkerCompleted()イベントを聞くことができますが、私が設定したデリゲートを呼び出すときに、完了したWorkerオブジェクトを知る必要があります。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." }); 
} 

私のワーカーオブジェクトがそのスタート()メソッドでループを終了したときに、私はRunWorkerCompleteEventArgsオブジェクトのuserStateプロパティを埋めるために何をしますか「E」 WorkerFinishedメソッド()に渡されますか?

おかげ

答えて

12

WorkerクラスのあなたのStart方法は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 argは自分のオブジェクトをe.Resultに持っています。 – sisdog

1

UserState事がBackgroundWorkerで既知のバグであること:

http://www.pluralsight-training.net/community/blogs/mike/archive/2005/10/21/15783.aspx(アーカイブ。 orgのリンク…元のリンクが死んでいる)

私はあなたの状況にしてきたとき、私が過去にやったことはを使用されますか(フィリップが示唆するように)、または、可能な場合はまだありながら、私の労働者は、その後、私は私が好きなだけの余分な状態を追加し、BackgroundWorkerによって発生したイベントへの送信者の引数として、全従業員を得ることができます(BackgroundWorkerから派生していますその意図する目的のためにResultを使用することができる)。

関連する問題