gpt4 book ai didi

c# - 等到我的 BackgroundWorker 完成才能打开新的 BackgroundWorker

转载 作者:行者123 更新时间:2023-11-30 13:47:33 26 4
gpt4 key购买 nike

在我的应用程序中,我在添加到我的列表框之前通过打开的 Wireshark 进程检查我的文件。这是添加目录单击事件,它获取根文件夹并检查此文件夹和子文件夹中的所有文件:

private void btnAddDir_Click(object sender, EventArgs e)
{
try
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
ThreadStart threadStart = delegate
{
foreach (string file in SafeFileEnumerator.EnumerateFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories))
{
Interlocked.Increment(ref numWorkers);
StartBackgroundFileChecker(file);
}
};

Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
}
catch (Exception)
{ }
}

private void StartBackgroundFileChecker(string file)
{
ListboxFile listboxFile = new ListboxFile();
listboxFile.OnFileAddEvent += listboxFile_OnFileAddEvent;
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork +=
(s3, e3) =>
{
//check my file
};

backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Interlocked.Decrement(ref numWorkers) == 0)
{
//update my UI
}
}

当我检查这个文件时,我打开了 Wireshark 进程,所以如果我选择包含许多文件的文件夹,许多 Wireshark 进程被打开,这会占用大量内存,我如何才能等到我的 BackgroundWorker 完成才打开新的?

最佳答案

据我了解,您希望一次只启动一个后台工作程序。如果是这样,那么试试这个(基于 System.Threading.AutoResetEvent )

//introduce additional field
private AutoResetEvent _workerCompleted = new AutoResetEvent(false);
//modify StartBackgroundFileChecker
private void StartBackgroundFileChecker(string file)
{
ListboxFile listboxFile = new ListboxFile();
listboxFile.OnFileAddEvent += listboxFile_OnFileAddEvent;
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork +=
(s3, e3) =>
{
//check my file
};

backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
//new code - wait for completion
_workerCompleted.WaitOne();
}
//add completion notification to backgroundWorker_RunWorkerCompleted
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Interlocked.Decrement(ref numWorkers) == 0)
{
//update my UI
}

//new code - notify about completion
_workerCompleted.Set();
}

在该解决方案中,您的后台线程将一个接一个地启动新的 BackgroundWorker - 这可能不是最优的(您可以完全避免使用 BackgroundWorker,只需通过 threadStart 委托(delegate)中的 Dispatch 更新 UI)

在我看来,最好控制并行线程的数量,并且仍然在多个但数量有限的线程中处理文件。

这是替代解决方案(基于 System.Threading.Tasks 命名空间):

 private void btnAddDir_Click(object sender, EventArgs e)
{
var selectedPath = folderBrowserDialog1.SelectedPath;
Task.Factory.StartNew(() =>
{

var files = Directory.EnumerateFiles(selectedPath, "*.*", SearchOption.AllDirectories);

Parallel.ForEach(files,
new ParallelOptions
{
MaxDegreeOfParallelism = 10 // limit number of parallel threads here
},
file =>
{
//process file here - launch your process
});
}).ContinueWith(
t => { /* when all files processed. Update your UI here */ }
,TaskScheduler.FromCurrentSynchronizationContext() // to ContinueWith (update UI) from UI thread
);
}

您可以根据您的特定需求调整此解决方案。

使用的类/方法(引用 MSDN):

  • Task
  • TaskScheduler.FromCurrentSynchronizationContext
  • Parallel.ForEach 方法(IEnumerable、ParallelOptions、Action)

关于c# - 等到我的 BackgroundWorker 完成才能打开新的 BackgroundWorker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16789878/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com