我正在为线程苦苦挣扎。
问题是当我迭代低谷的foreach循环时。

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

问题在于,在我可以对第一个文件执行此操作之前,this.Document已经更改,从而使应用程序执行另一次登录。这样,我将永远无法真正执行自己的动作。

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

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

这是代码:

    public void Start(object obj)
    {
       try
       {
          foreach (KeyValuePair<string, Stream> 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<ActionEvent>().Publish(new Message(EMessageType.Info) { Title = dataHolder.FileName });
    }

最佳答案

9号

请尝试以下操作:

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


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

让我知道它是否有效:)

07-26 08:39