使用List <thread> </thread>管理线程

时间:2011-11-06 16:32:40

标签: c# multithreading

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

基本理念是:

  1. 会有很多线程进程调用一个函数,并且每个线程都不会被调用。

  2. 我想限制最大线程数。

  3. 线程完成后,我想调用另一个线程,直到完成所有操作。

  4. 为了实现这一点,我使用了一个线程列表。对于每一秒,我检查列表是否已满,以及是否有任何线程完成其工作。

    这是我的代码:

    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();
    }
    

    这样可行,但我认为我在这里不优雅高效,如何改进我的代码呢?

2 个答案:

答案 0 :(得分:5)

这不是解决问题的正确方法。 您不需要保留线程列表,只需在所有线程完成运行时通知应用程序。

这是一种处理问题的可能方法,使用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

答案 1 :(得分:4)

结帐TPL和/或ThreadPool