暂停新的BackGroundWorker直到上一次完成

我正在努力进行线程化。 问题是当我通过foreach循环迭代时。

设置this.Document ,应用程序执行登录,该事件由事件触发并需要几秒钟才能完成。 在worker_RunWorkerCompleted方法中,我需要执行一些依赖于当前登录信息的操作。

问题是,在我可以对第一个文件执行此操作之前, this.Document已经更改,使应用程序执行另一次登录。 这样我就无法实际执行我的操作。

我的问题是:如何在上一个线程完成之前暂停下一个线程。 我的问题还有其他解决办法吗?

我尝试使用AutoResetEvent但我没有运气。 我在RunWorkerAsync调用之后设置了waitOne() ,并在RunWorkerCompleted中设置了.Set() 。 代码永远不会到达RunWorkerCompleted ……

这是代码:

  public void Start(object obj) { try { foreach (KeyValuePair pair in this.CollectionOfFiles) { Worker = new BackgroundWorker(); Worker.DoWork += new DoWorkEventHandler(worker_DoWork); Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); using (Stream stream = pair.Value) { primaryDocument = new Document(stream); DataHolderClass dataHolder = new DataHolderClass(); dataHolder.FileName = pair.Key; dataHolder.Doc = secondaryDocument; //background thread call Worker.RunWorkerAsync(dataHolder); } } } catch (Exception ex) { // exception logic } finally { // complete logic } } private void worker_DoWork(object sender, DoWorkEventArgs e) { DataHolderClass dataHolder = ((DataHolderClass)e.Argument); // setting this attribute triggers execution of login event this.Document = dataHolder.Doc; e.Result = (dataHolder); } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // here I need to perform some actions that are depending on the current login DataHolderClass dataHolder = ((DataHolderClass)e.Result); this.eventAggregator.GetEvent().Publish(new Message(EMessageType.Info) { Title = dataHolder.FileName }); } 

NO9,

请尝试以下方法:

 System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(false); void ResumeWorker() { // Start the worker if it isn't running if (!backgroundWorker1.IsBusy) backgroundWorker1.RunWorkerAsync(dataHolder); // Unblock the worker _busy.Set(); } void PauseWorker() { // Block the worker _busy.Reset(); } void CancelWorker() { if (backgroundWorker1.IsBusy) { // Set CancellationPending property to true backgroundWorker1.CancelAsync(); // Unblock worker so it can see that _busy.Set(); } } 

然后在你的代码中运行该方法。

让我知道它是否有效:)

 class SimpleWaitPulse { static readonly object _locker = new object(); static bool _go; static void Main() { // The new thread will block new Thread (Work).Start(); // because _go==false. Console.ReadLine(); // Wait for user to hit Enter lock (_locker) // Let's now wake up the thread by { // setting _go=true and pulsing. _go = true; Monitor.Pulse (_locker); } } static void Work() { lock (_locker) while (!_go) Monitor.Wait (_locker); // Lock is released while we're waiting Console.WriteLine ("Woken!!!"); } } 

你能用脉冲吗? 摘自: 来自albahari.com的C#中的线程

嗯,设计很糟糕……但是如果需要坚持下去,你可以在之前的工作人员中设置等待句柄并在下一个等待它。 这是最小的修复,仍然是令人厌恶的:

 public void Start(object obj) { try { BackgroundWorker previousWorker = null; DataHolderClass previousWorkerParams = null; foreach (KeyValuePair pair in this.CollectionOfFiles) { // signal event on previous worker RunWorkerCompleted event AutoResetEvent waitUntilCompleted = null; if (previousWorker != null) { waitUntilCompleted = new AutoResetEvent(false); previousWorker.RunWorkerCompleted += (o, e) => waitUntilCompleted.Set(); // start the previous worker previousWorker.RunWorkerAsync(previousWorkerParams); } Worker = new BackgroundWorker(); Worker.DoWork += (o, e) => { // wait for the handle, if there is anything to wait for if (waitUntilCompleted != null) { waitUntilCompleted.WaitOne(); waitUntilCompleted.Dispose(); } worker_DoWork(o, e); }; using (Stream stream = pair.Value) { primaryDocument = new Document(stream); DataHolderClass dataHolder = new DataHolderClass(); dataHolder.FileName = pair.Key; dataHolder.Doc = secondaryDocument; // defer running this worker; we don't want it to finish // before adding additional completed handler previousWorkerParams = dataHolder; } previousWorker = Worker; } if (previousWorker != null) { previousWorker.RunWorkerAsync(previousWorkerParams); } } catch (Exception ex) { // exception logic } finally { // complete logic } }