Results 1 to 11 of 11

Thread: [RESOLVED] how to make main thread wait for all threads before continuing?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Resolved [RESOLVED] how to make main thread wait for all threads before continuing?

    I have this code:

    Code:
    for (int i = 0; i < 4; i++)
    {
      Thread t = new Thread(new ThreadStart(Proc));
      t.Start();
    }
    
    //I want main thread to wait (in this case, for 4 threads to complete) before calling the codes below
    Console.Write("Complete");
    Any ideas?

  2. #2
    Hyperactive Member Cyb3rH4Xter's Avatar
    Join Date
    May 2009
    Location
    Sweden
    Posts
    449

    Re: how to make main thread wait for all threads before continuing?

    You probably could do a while loop checking the Thread.IsAlive or Thread.ThreadState every 5 seconds or something:

    Code:
    while (t.IsAlive == true)
    {
        Thread.Sleep(5000)
    }
    Sorry if the code doesn't work, coded it without VS.

    EDIT: The task is yours to make that code work with 4 threads and not just one

  3. #3
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: how to make main thread wait for all threads before continuing?

    Don't do thread synchronisation by hand. Polling for completion of a background thread is an utterly horrible way of doing things. Spinning up new threads by hand is almost always the wrong thing to do as well. If you have C#4, you can use the new TPL to handle all of this for you:

    csharp Code:
    1. List<Task> tasks = new List<Task>();
    2. for (int i = 0; i < 4; i++)
    3. {
    4.     tasks.Add(Task.Factory.StartNew(Proc));
    5. }
    6.  
    7. Task.WaitAll(tasks.ToArray());
    8. Console.WriteLine("Complete");

    The WaitAll method will block until all the Tasks passed to it have finished.

    If you don't have C#4, I would suggest decorating your Proc call with a WaitHandle that you use to wait on:

    csharp Code:
    1. List<WaitHandle> waitHandles = new List<WaitHandle>();
    2. for (int i = 0; i < 4; i++)
    3. {
    4.     ManualResetEvent waitHandle = new ManualResetEvent(false);
    5.     waitHandles.Add(waitHandle);
    6.     Thread t = new Thread(new ThreadStart(() =>
    7.                                                 {
    8.                                                     Proc();
    9.                                                     waitHandle.Set();
    10.                                                 }));
    11.     t.Start();
    12. }
    13. WaitHandle.WaitAll(waitHandles.ToArray());
    14. Console.WriteLine("Complete");

    Of course, this doesn't stop you starting threads by hand, I'd suggest if you need to use this route to use the ThreadPool to stop the overhead of thread creation/destruction.

  4. #4
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: how to make main thread wait for all threads before continuing?

    Just out of curiosity, what is the content of your Proc method? You will usually find that if it's something that causes blocking (such as disk or network I/O) then there is an asynchronous API as well that let's you do things in parallel without needing to multithread your app.

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Re: how to make main thread wait for all threads before continuing?

    Quote Originally Posted by Evil_Giraffe View Post
    Just out of curiosity, what is the content of your Proc method? You will usually find that if it's something that causes blocking (such as disk or network I/O) then there is an asynchronous API as well that let's you do things in parallel without needing to multithread your app.
    Thanks for all the replies. I'm trying to create my own web service stress tester, so I need a bunch of threads to make multiple requests. Will using the waitall method cause the form to hang? I'd like to be able to move the windows form even while the rest of the threads are doing their job.

  6. #6
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: how to make main thread wait for all threads before continuing?

    Yes, the form will hang if you call WaitAll from the UI thread. That blocks the thread that makes the call until everything it is waiting for completes.

    The web request API should give you an async version of its methods (BeginRequest/EndRequest). Learning how to use these methods is probably the better way for you to go here.

    Alternatively, if you are using the Task Parallel Library (first code snippet I posted) you can do the same thing with continuations. These are bits of code that get scheduled once a task has completed. You can schedule them on the UI thread if they need to update the UI.

    I'd suggest reading up on those two areas (bit hard to give you everything you need to know in a single post) and coming back if you have more questions.

  7. #7

    Thread Starter
    Frenzied Member
    Join Date
    Jul 2005
    Posts
    1,168

    Re: how to make main thread wait for all threads before continuing?

    I was able to figure out a solution. I just created another thread (that will be in a loop) to basically call the control.invoke() method, which allows the main thread to do it's own updating of the controls (ie. labels).

  8. #8
    New Member
    Join Date
    Aug 2019
    Location
    Hawaii
    Posts
    3

    Re: how to make main thread wait for all threads before continuing?

    Quote Originally Posted by Evil_Giraffe View Post
    Don't do thread synchronisation by hand. Polling for completion of a background thread is an utterly horrible way of doing things. Spinning up new threads by hand is almost always the wrong thing to do as well. If you have C#4, you can use the new TPL to handle all of this for you:

    csharp Code:
    1. List<Task> tasks = new List<Task>();
    2. for (int i = 0; i < 4; i++)
    3. {
    4.     tasks.Add(Task.Factory.StartNew(Proc));
    5. }
    6.  
    7. Task.WaitAll(tasks.ToArray());
    8. Console.WriteLine("Complete");

    The WaitAll method will block until all the Tasks passed to it have finished.

    If you don't have C#4, I would suggest decorating your Proc call with a WaitHandle that you use to wait on:

    csharp Code:
    1. List<WaitHandle> waitHandles = new List<WaitHandle>();
    2. for (int i = 0; i < 4; i++)
    3. {
    4.     ManualResetEvent waitHandle = new ManualResetEvent(false);
    5.     waitHandles.Add(waitHandle);
    6.     Thread t = new Thread(new ThreadStart(() =>
    7.                                                 {
    8.                                                     Proc();
    9.                                                     waitHandle.Set();
    10.                                                 }));
    11.     t.Start();
    12. }
    13. WaitHandle.WaitAll(waitHandles.ToArray());
    14. Console.WriteLine("Complete");

    Of course, this doesn't stop you starting threads by hand, I'd suggest if you need to use this route to use the ThreadPool to stop the overhead of thread creation/destruction.
    this codes will freeze the UI.

  9. #9
    coder. Lord Orwell's Avatar
    Join Date
    Feb 2001
    Location
    Elberfeld, IN
    Posts
    7,621

    Re: [RESOLVED] how to make main thread wait for all threads before continuing?

    we've known that since Jul 13th, 2011, 06:04 PM. There's another option available that could be used. The Parallel.For and Parallel.ForEach do all the threading for you. You'll still have ui issue though.
    My light show youtube page (it's made the news) www.youtube.com/@artnet2twinkly
    Contact me on the socials www.facebook.com/lordorwell

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: [RESOLVED] how to make main thread wait for all threads before continuing?

    You can use async/await to allow you to await multiple tasks without freezing the UI. Not sure that that was available when this thread was originally active.

  11. #11
    New Member
    Join Date
    Aug 2019
    Location
    Hawaii
    Posts
    3

    Re: [RESOLVED] how to make main thread wait for all threads before continuing?

    Quote Originally Posted by Lord Orwell View Post
    we've known that since Jul 13th, 2011, 06:04 PM. There's another option available that could be used. The Parallel.For and Parallel.ForEach do all the threading for you. You'll still have ui issue though.
    Parallel does not solve the UI freeze.

    Quote Originally Posted by jmcilhinney View Post
    You can use async/await to allow you to await multiple tasks without freezing the UI. Not sure that that was available when this thread was originally active.
    I can use Task or async/await but I don't know which one is better?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width