Я не думаю, что сценарий действительно состоит в том, что один BackgroundWorker
должен ждать другого. Что вы действительно хотите, так это запускать какое-то событие пользовательского интерфейса после (и только после) завершения обоих из них. Это тонкое, но важное различие; вторая версия намного проще для кодирования.
public class Form1 : Form
{
private object download1Result;
private object download2Result;
private void BeginDownload()
{
// Next two lines are only necessary if this is called multiple times
download1Result = null;
download2Result = null;
bwDownload1.RunWorkerAsync();
bwDownload2.RunWorkerAsync();
}
private void bwDownload1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
download1Result = e.Result;
if (download2Result != null)
DisplayResults();
}
private void bwDownload2_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
download2Result = e.Result;
if (download1Result != null)
DisplayResults();
}
private void DisplayResults()
{
// Do something with download1Result and download2Result
}
}
Обратите внимание, что эти object
ссылки должны быть строго напечатаны, я просто использовал object
, потому что я не знаю, что вы скачиваете.
Это действительно все, что вам нужно; Событие RunWorkerCompleted
выполняется в потоке переднего плана, поэтому вам не нужно беспокоиться о синхронизации или условиях гонки. Нет необходимости в операторах lock
, AutoResetEvent
и т. Д. Просто используйте две переменные-члены для хранения результатов или два логических флага, если результатом любого из них может быть null
.