Reputation: 2864
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
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
Reputation: 30820
You can use AutoResetEvent
for this:
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
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
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