Rohit Raghuvansi
Rohit Raghuvansi

Reputation: 2864

Best way to wait for a background thread to finish processing in C#

I have a background thread. If the background thread is busy, I want to wait for it to finish its work and then continue with next request. I have implemented it in the following way. Process is the name of the background thread.

 if (process.IsBusy)
 {
     do
     {
         isProcessBusy = process.IsBusy;
     } while (isProcessBusy == false);

     SetIsDirty(status, GetContext());
 }
 else
 {
     SetIsDirty(status, GetContext());
 }

Is this the best way or are there other ways to implement this kind of logic?

Upvotes: 4

Views: 6645

Answers (5)

AlessandroG
AlessandroG

Reputation: 318

The way to block one thread, waiting the end of another thread, is called locking. C# allows us to lock our code with either a Monitor class or a lock { } construct. Have a look to this.

For exemple:

 Class1()
            {
                  // construct two threads for our demonstration;
                  Thread thread1 = new Thread(new ThreadStart(DisplayThread1));
                  Thread thread2 = new Thread(new ThreadStart(DisplayThread2));

                  // start them
                  thread1.Start();
                  thread2.Start();
            }

        void DisplayThread1()
        {
              while (_stopThreads == false)
              {
                  // lock on the current instance of the class for thread #1
                    lock (this)
                    {
                          Console.WriteLine("Display Thread 1");
                          _threadOutput = "Hello Thread1";
                          Thread.Sleep(1000);  // simulate a lot of processing
                          // tell the user what thread we are in thread #1
                          Console.WriteLine("Thread 1 Output --> {0}", _threadOutput);
                    } // lock released  for thread #1 here
              } 
        }

        void DisplayThread2()
        {
              while (_stopThreads == false)
              {

                  // lock on the current instance of the class for thread #2
                    lock (this)
                    {
                          Console.WriteLine("Display Thread 2");
                          _threadOutput = "Hello Thread2";
                          Thread.Sleep(1000);  // simulate a lot of processing
                          // tell the user what thread we are in thread #1
                          Console.WriteLine("Thread 2 Output --> {0}", _threadOutput);
                    }  // lock released  for thread #2 here
              } 
        }

}

Upvotes: 0

decyclone
decyclone

Reputation: 30820

You can use AutoResetEvent for this:

Example:

AutoResetEvent resetEvent = new AutoResetEvent(false);

private void StartProcess()
{
    new Thread(DoProcess).Start();
}

private void DoProcess()
{
    List<String> list = new List<String>() { 
        "Value 1",
        "Value 2",
        "Value 3",
        "Value 4",
        "Value 5",
    };

    foreach (String item in list)
    {
        process.RunWorkerAsync(item);

        if (!resetEvent.WaitOne())
        {
            // Some exception
            break;
        }
        resetEvent.Reset();
    }
}

private void process_DoWork(object sender, DoWorkEventArgs e)
{
    Debug.WriteLine(e.Argument.ToString());
    Thread.Sleep(1000);
}

private void process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    resetEvent.Set();
}

Upvotes: 2

Danish Khan
Danish Khan

Reputation: 1891

This is not recommended at all. This way you would always be utilising your CPU without doing any actual work.

If you want to use the same approach, use some Wait Handles or Sleep before you check if the thread is active.

However, I would recommend checking this article for getting a better understanding on background threads and different synchronisation approaches.

OR

you can also consider using ThreadPool for handling the background tasks. Here is an example from Microsoft for the same.

Upvotes: 2

Daniel Mošmondor
Daniel Mošmondor

Reputation: 19956

Is you want to wait until some task is done, use Thread.Sleep(0) or Thread.Sleep(100) to avoid burning 100 percent of the CPU core just for waiting one flag to be raised.

There are methods with events and semaphores, but this one is simple and it won't hurt a bit.

Upvotes: 0

Itay Karo
Itay Karo

Reputation: 18286

The Thread class has a method named Join that blocks until the thread on which it is being called exits.
Take a look at here.

Upvotes: 6

Related Questions