我正在为线程苦苦挣扎。
问题是当我迭代低谷的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();
}
}
然后在您的代码中运行该方法。
让我知道它是否有效:)