循环文件夹中的文件并将每个文件添加到线程中,但一次只运行其中一个线程
本文关键字:线程 文件 一次 文件夹 运行 一个 添加 循环 | 更新日期: 2023-09-27 17:53:11
我有一个文件夹,里面有几个文件。我有一个循环,它将遍历每个文件,并将其添加到线程中,以便在后台处理,以便UI响应。问题是我想在给定时间只运行一个线程。所以基本上我想让线程"排队",当一个线程完成后,启动下一个线程。最好的方法是什么?这是我使用的代码。我想知道计时器是否是最好的解决方案?谢谢所有人。
foreach (CustomerFile f in CF)
{
btnGo.Enabled = false;
UpdateProgressDelegate showProgress = new UpdateProgressDelegate(UpdateProgress);
ProcessFile pf = new ProcessFile(this, showProgress, f._FileName, txtDestFolder.Text);
Thread t = new Thread(new ThreadStart(pf.DoWork));
t.IsBackground = true;
t.Start();
}
如何将文件添加到队列并在另一个线程上处理队列?
Queue<CustomerFile> files = new Queue<CustomerFile>()
foreach (CustomerFile f in CF)
files.Enqueue(f);
BackgroundWorker bwk = new BackgroundWorker();
bwk.DoWork+=()=>{
//Process the queue here
// if you update the UI don't forget to call that on the UI thread
};
bwk.RunWorkerAsync();
这是生产者消费者模型,这是一个非常常见的需求。在c#中,BlockingCollection
是这个任务的理想选择。让生产者将项目添加到该集合中,然后让后台任务(可以有任意数量的后台任务)从该集合中获取项目。
听起来您可以只使用一个处理队列的后台线程。像这样:
var q = new Queue();
foreach (var file in Directory.GetFiles("path"))
{
q.Enqueue(file);
}
var t = new Task(() =>
{
while (q.Count > 0)
{
ProcessFile(q.Dequeue());
}
});
t.Start();
注意,这只适用于在后台线程处理队列时不需要修改队列的情况。如果是这样,Servy的答案是正确的:这是一个非常标准的生产者-消费者问题,只有一个消费者。有关解决生产者/消费者问题的更多信息,请参阅Albahari's Threading in c#。
你唯一要做的就是把你的循环放在一个线程中,例如:
new Thread(()=>{
foreach (CustomerFile f in CF)
{
btnGo.Enabled = false;
UpdateProgressDelegate showProgress = new UpdateProgressDelegate(UpdateProgress);
ProcessFile pf = new ProcessFile(this, showProgress, f._FileName, txtDestFolder.Text);
pf.DoWork();
}
}).Start();