2

I'm trying to implement a multithread in c#.

The basic idea is:

  1. There will be a lot of thread process calling a function and every thread doesn't end in order they are called.

  2. I want to limit maximum number of thread running.

  3. When a thread is finished, I want to call another thread until everything is done.

So to implement this, I use a list of thread. For every second, I check if there the list is already full and if there's any thread finished its job.

Here is my code:

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

This works, but I don't think I'm being elegant and efficient here, how can I improve my code?

3
  • 2
    Use ThreaPool and/or TPL (Fx 4). Commented Nov 6, 2011 at 16:43
  • I think it's valid to do like you do. Just a change to remove the sleep. Add another list to act as a queue. If the thread company list is full add it to the queue list instead. Then add an event to the worker that triggers when the package is completed. Then start the next job in the queue. Everything is done when the threads in the thread company list are all finihed and the queue is empty. Commented Nov 6, 2011 at 16:54
  • there is only 1241912901 ways to mess this up if you use your own thread pool implementation. Commented Nov 6, 2011 at 17:43

2 Answers 2

5

This is not the right way to solve the problem. You don't need to keep a list of your threads, you just need to notify the application when all thread finish running.

This is a possible way to handle the problem using SynchronizationContext to notify the main thread when execution completes, without any kind of wait cycle.

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

If you just want to you run in a multiprocessor machne assigning a thread for each processor you can just use Parallel.For

Sign up to request clarification or add additional context in comments.

Comments

4

check out TPL and/or ThreadPool.

1 Comment

Yahia if you can provide a working sample in his context will be useful :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.