使用List管理线程

本文关键字:管理 线程 Thread List 使用 | 更新日期: 2023-09-27 18:13:35

我正在尝试在c#中实现多线程。

基本思想是:

  1. 会有很多线程进程调用一个函数,并且每个线程并不按照它们被调用的顺序结束。

  2. 我想限制线程运行的最大数量

  3. 当一个线程结束时,我想调用另一个线程,直到一切都完成。

因此,为了实现这一点,我使用线程列表。每一秒钟,我检查列表是否已经满了,是否有线程完成了它的工作。

下面是我的代码:
List<Thread> threadCompany = new List<Thread>();
List<Thread> fireThisGuy = new List<Thread>();
while (i < _finish) {
    if (threadCompany.Count < _MAX_THREAD) {
        Thread worker = new Thread(delegate() {
            CallFunction(i);
        });
        threadCompany.Add(worker);
        i++;
        worker.Start();
    }
    Thread.Sleep(1000); //Wait for a while instead of keep calling if
    foreach (Thread worker in threadCompany) { 
        if (!worker.IsAlive) {
            fireThisGuy.Add(worker); //because threadCompany may not be 
                                     //modified in iteration.
        }
    }
    foreach (Thread worker in fireThisGuy) {
        threadCompany.Remove(worker);
    }
    fireThisGuy.Clear();
}

这是有效的,但我不认为我在这里是优雅和高效的,我该如何改进我的代码?

使用List<Thread>管理线程

这不是解决问题的正确方法。你不需要保存一个线程列表,你只需要在所有线程结束运行时通知应用程序。

这是一个可能的方法来处理问题,使用SynchronizationContext通知主线程,当执行完成时,没有任何类型的等待周期。

public class OwnerClass
{
    private SynchronizationContext syncContext;
    private int count;
    private int completedCount;
    // This event will be raised when all thread completes
    public event EventHandler Completed;
    public OwnerClass() :
        this(SynchronizationContext.Current)
    {
    }
    public OwnerClass(SynchronizationContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        this.syncContext = context;
    }
    // Call this method to start running
    public void Run(int threadsCount)
    {
        this.count = threadsCount; 
        for (int i = 0; i < threadsCount; ++i)
        {
            ThreadPool.QueueUserWorkItem(this.ThreadFunc, null);
        }
    }
    private void ThreadFunc(object threadContext)
    {
        Thread.Sleep(1000); /// my long and complicated function
        if (Interlocked.Increment(ref this.completedCount) >= this.count)
        {
            this.syncContext.Post(OnCompleted, null);
        }
    }
    protected virtual void OnCompleted(object state)
    {
        var handler = this.Completed;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }
}

如果你想在一个多处理器的机器上运行,为每个处理器分配一个线程,你可以使用Parallel.For

查看TPL和/或ThreadPool