0

所以我有一个包含几个文件的文件夹。我有一个循环,它将遍历每个文件并将其添加到线程中以在后台处理,以便 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();
}
4

4 回答 4

2

如何将文件添加到队列并在另一个线程上处理队列?

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();
于 2013-01-15T14:47:16.700 回答
1

这是生产者消费者模型,这是一个非常普遍的需求。在 C# 中BlockingCollection,这是此任务的理想选择。让生产者将项目添加到该集合中,然后让后台任务(您可以拥有任意数量)从该集合中获取项目。

于 2013-01-15T14:50:53.247 回答
1

听起来您只需一个处理队列的后台线程就可以逃脱。像这样的东西:

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 的C# 中的线程。

于 2013-01-15T14:51:33.780 回答
0

你唯一必须做的就是把你的循环放在一个线程中,例如这样的:

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();
于 2013-01-15T17:27:59.007 回答