BlockingCollection class: Does thread yield if Take blocks? - c#

MSDN said that BlockingCollection.Take call blocks if there is no elements in it. Does it mean the thread will yield the timeslice and go to the waiting threads queue?
If yes does it mean that the thread will change its state to Ready once the blocking collection received an item and then will be scheduled to next timeslice as per usual rules?

Yes. When you call Take() on a BlockingCollection<T>, the thread will sit blocked (waiting on an event handle) until an element is added to the collection from another thread. This will cause that thread to give up its time slice.
When an element is added to the collection, the thread will get signaled to continue, get the element, and continue on.

I thought this might be interesting for further readers. This is how I established this for fact.
class Program
{
static BlockingCollection<int> queue = new BlockingCollection<int>();
static Thread th = new Thread(ThreadMethod);
static Thread th1 = new Thread(CheckMethod);
static void Main(string[] args)
{
th.Start();
th1.Start();
for (int i = 0; i < 100; i++)
{
queue.Add(i);
Thread.Sleep(100);
}
th.Join();
Console.ReadLine();
}
static void ThreadMethod()
{
while (!queue.IsCompleted)
{
int r = queue.Take();
Console.WriteLine(r);
}
}
static void CheckMethod()
{
while (!queue.IsCompleted)
{
Console.WriteLine(th.ThreadState);
Thread.Sleep(48);
}
}
}

Related

Not getting expected output in the Multithreading question

Task description:
Write a program that reads an positive integer value n (n > 3), then
creates n threads (each thread has id; id starts from 1) and works
until it receives a stop signal. All of n threads are waiting for a
signal. Every second main thread sends a signal for a random thread,
then that thread should print its id and return to a waiting state.
Requirements:
All additional threads should be finished correctly. At the thread
function exit, a message about exit should be printed. While the
thread is waiting for the condition variable, spurious wakeup should
be checked. Only std::cout allowed for text output. Stop signal is
SIGINT (ctrl+c).
I have written the following code for the above question but in output, all the threads are not exiting. I am not able to figure out the problem as I am new to this topic. Any kind of help will be really appreciated.
class Program
{
public static void Main()
{
var numberofthreads = Convert.ToInt32(Console.ReadLine());
ProcessingClass myobject = new ProcessingClass();
myobject.createThreads(numberofthreads);
}
}
public class ProcessingClass
{
public Mutex mymutex = new Mutex();
private bool thread_flag = false;
public void createThreads(int numberofthreads)
{
var threads = new List<Thread>(numberofthreads);
for (int i = 0; i < numberofthreads; i++)
{
Thread th = new Thread(() =>
{
threadsworking();
});
th.Name = "Thread" + i;
th.Start(); // <-- .Start() makes the thread start running
threads.Add(th);
}
Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) =>
{
var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC;
if (isCtrlC)
{
thread_flag = true;
int num = 1;
foreach (var thread in threads)
{
thread.Join();
Console.WriteLine($"Thread {num} exits");
num++;
}
}
e.Cancel = true;
};
}
public void threadsworking()
{
while (thread_flag == false)
{
mymutex.WaitOne(); // Wait until it is safe to enter.
Console.WriteLine("{0}", Thread.CurrentThread.Name);
Thread.Sleep(1000); // Wait until it is safe to enter.
mymutex.ReleaseMutex(); // Release the Mutex.
}
}
}
enter image description here
Consider preventing mutex from blocking threads from exiting.
When you use mutex.WaitOne() it blocks execution until the Mutex is owned by that thread. This can be really helpful for ensuring a thread has exclusive control over a shared resource. However, where this becomes a problem is when you want to arbitrarily end those threads such as when you invoke the event on the Console.CancelKeyPress.
You can see the effects of this by logging before and after the thread.Join() call you do in the event.
thread_flag = true;
int num = 1;
foreach (var thread in threads)
{
Console.WriteLine($"Joining {thread.Name}");
thread.Join();
Console.WriteLine($"Joined {thread.Name}");
Console.WriteLine($"Thread {num} exits");
num++;
}
When we do that logging it will show us that when you call Join() on Thread # 1 you see Joining 1. Then there is a really long pause, other threads still are doing work, and then finally all the threads join back to back.
The reason for this is - while Join() is waiting for Thread 1 to finish, Thread 1 is still waiting for the mutex.
Even though you set the thread_flag flag to true, Thread 1 can't exit because it hasn't taken ownership of the mutex to perform it's work and eventually exit the while() loop.
We can solve this issue fairly simply.
Consider using a timeout when waiting for the mutex
When you call .WaitOne(n) on the mutex you can wait for n given milliseconds and give up taking ownership of the mutex.
This will allow more frequent evaluations of the while loop, and subsequently more times that the threadsworking method checks to see if it should exit(using the thread_flag flag).
Heres a short example how implementing that change might look
public void threadsworking()
{
while (thread_flag == false)
{
// wait to enter the mutex, give timeout to prevent blocking
// until mutex opens and use the bool returned to determine
// if we should release the mutex or not
if (mymutex.WaitOne(1))
{
try
{
Console.WriteLine("{0}", Thread.CurrentThread.Name);
Thread.Sleep(1000); // Wait until it is safe to enter.
}
finally
{
// make sure even if we encounter an error the mutex is released
mymutex.ReleaseMutex(); // Release the Mutex.
}
}
// allow other threads to continue their work instead of blocking with a while loop, this is optional depending on the workload
Thread.Yield();
}
}

How to stop task(thread) and release in other task? [duplicate]

Hi guys I start threads with such code:
Thread[] thr;
private void button1_Click(object sender, EventArgs e)
{
decimal value = numericUpDown2.Value;
int i = 0;
threads_count = (int)(value);
thr = new Thread[threads_count];
for (; i < threads_count; i++)
{
thr[i] = new Thread(new ThreadStart(go));
thr[i].IsBackground = true;
thr[i].Start();
}
}
How to stop all them if my condition become true
A number of the answers say to abort the thread. Never abort a thread unless it is an emergency situation and you are shutting down the application.
The CLR guarantees that its internal data structures are not corrupted by a thread abort. This is the only (*) guarantee made by the CLR with respect to thread aborts. It specifically does not guarantee:
That the thread actually will abort. Threads can harden themselves against being terminated.
That any data structure that is not in the CLR itself will be uncorrupted. Thread aborts in the middle of crucial operations can leave BCL data structures or user data structures in arbitrarily inconsistent states. This can crash your process mysteriously later.
That locks will be released. Aborting threads can cause locks to be held forever, it can cause deadlocks, and so on.
In case I am not being clear: it is insanely dangerous to abort a thread and you should only do so when all the alternatives are worse.
So what if you want to start up a thread and then shut it down cleanly?
First, don't do that. Don't start a thread in the first place. Start a Task<T> with a cancellation token and when you want to shut it down, signal its cancellation token.
If you do have to start a thread, then start the thread such that there is some mechanism whereby the main thread and the working thread can cleanly and safely communicate "I want you to shut yourself down cleanly at this time".
If you don't know how to do that then stop writing multithreaded code until you learn how to do that.
(*) This is a small lie; the CLR also makes certain guarantees with respect to the interactions of thread aborts and special code regions such as constrained execution regions and finally blocks.
You can use a CancellationToken to signal when the operation should stop.
Create a CancellationTokenSource as an instance field of your type that you initialize in the button click handler.
In your background method periodically check the IsCancellationRequested property of the Token in the token source, or call ThrowIfCancellationRequested() if you want it to just throw an exception if it is canceled.
When you want to stop the threads call Cancel on the token source.
Brutal way (not recommended) - use Thread.Abort method to abort threads. This method raises ThreadAbortException on thread. Like this:
foreach(Thread thread in thr)
thread.Abort();
But better way is notifying thread about cancellation and letting it correctly finish its job. You can do it simply with .Net 4 tasks:
Task[] thr = new Task[threads_count];
var source = new CancellationTokenSource();
for (int i = 0; i < threads_count; i++)
{
thr[i] = Task.Factory.StartNew(go, source.Token);
}
// later, when condition is met
source.Cancel();
And here is how cancellation should look like:
private static void go(object obj)
{
CancellationToken token = (CancellationToken)obj;
while (true)
{
if (token.IsCancellationRequested)
return;
// do some work
}
}
If you want to know how to terminate the thread gracefully, I'd recommend you to take a look the following example on MSDN:
using System;
using System.Threading;
public class Worker
{
public void DoWork()
{
while (!_shouldStop)
{
Console.WriteLine("worker thread: working...");
}
Console.WriteLine("worker thread: terminating gracefully.");
}
public void RequestStop()
{
_shouldStop = true;
}
// Volatile is used as hint to the compiler that this data
// member will be accessed by multiple threads.
private volatile bool _shouldStop;
}
public class WorkerThreadExample
{
static void Main()
{
Worker workerObject = new Worker();
Thread workerThread = new Thread(workerObject.DoWork);
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread...");
while (!workerThread.IsAlive); // Loop until worker thread activates
// Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(1);
workerObject.RequestStop();
// Use the Join method to block the current thread
// until the object's thread terminates.
workerThread.Join();
Console.WriteLine("main thread: Worker thread has terminated.");
}
}
This is Windows Form Code in which:
1) On Clicking start button, Main Thread creates another Thread
2) Again created Thread creates on more Thread.
3) On clicking Stop button, First the last Thread should terminate Then the Thread created by Main thread should Terminate.
namespace Thread_TerminateProblem
{
public partial class Form1 : Form
{
private static AutoResetEvent m_ResetEvent = null;
private static ManualResetEvent m_ResetEvent_Thread = new ManualResetEvent(false);
enum ServiceState { Start, Stop };
bool flag = false;
int x = 0;
ServiceState _state;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
flag = true;
_state = ServiceState.Start;
m_ResetEvent = new AutoResetEvent(true);
Thread t1 = new Thread(fun_Thread1);
t1.Start();
t1.Name = "Thread1";
}
private void btnStop_Click(object sender, EventArgs e)
{
_state = ServiceState.Stop;
m_ResetEvent.Set();
}
private void fun_Thread1()
{
while (true)
{
m_ResetEvent.WaitOne();
switch (_state)
{
case ServiceState.Start:
{
Thread t = new Thread(fun_Thread2);
t.Start();
t.Name = "Thread2";
break;
}
case ServiceState.Stop:
{
m_ResetEvent_Thread.Set();
flag = true;
break;
}
}
// When the child Thread terminates, Then only this thread should terminate
if (flag == true)
{
// Waiting for notification from child Thread
notifyParent.WaitOne();
Thread.Sleep(100);
break;
}
m_ResetEvent.Reset();
}
}
private static ManualResetEvent notifyParent = new ManualResetEvent(false);
private void fun_Thread2()
{
while (true)
{
if (m_ResetEvent_Thread.WaitOne(1, false))
{
notifyParent.Set();
break;
}
x++;
}
}
}
}
simplistic answer is to use the thread Abort() method however your code does not really make it clear what condition,
what loop tests vs a condition? why do you need to abort a thread? I am asking as there may be a better way to approach this

Communicate to the UI thread when a thread completes

I have a simple program here below that has 2 threads performing some task.
Thread1 is the data feeder. Thread2 is the data processor.
So far the work being done through my approach is working but I want to have better way of getting notified when the work completes
Here is the code
class Program
{
private static BlockingCollection<int> _samples = new BlockingCollection<int>();
private static CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private static bool _cancel;
static void Main(string[] args)
{
ThreadStart thread1 = delegate
{
ProcessThread1();
};
new Thread(thread1).Start();
ThreadStart thread2 = delegate
{
ProcessThread2();
};
new Thread(thread2).Start();
Console.WriteLine("Press any key to cancel..");
Console.Read();
_cancel = true;
_cancellationTokenSource.Cancel();
Console.Read();
}
private static void ProcessThread1()
{
for (int i = 0; i < 10; i++)
{
if (_cancel)
{
break;
}
Console.WriteLine("Adding data..");
_samples.TryAdd(i,100);
Thread.Sleep(1000);
}
// I dont like this. Instead can I get notified in the UI thread that this thread is complete.
_cancel = true;
_cancellationTokenSource.Cancel();
}
private static void ProcessThread2()
{
while (!_cancellationTokenSource.IsCancellationRequested)
{
int data;
if (_samples.TryTake(out data, 100))
{
// Do some work.
Console.WriteLine("Processing data..");
}
}
Console.WriteLine("Cancelled.");
}
}
I want the program to exit if the cancel is requested by the user or when the work completes.
I am not sure how I can get notified when the ProcessThread1 runs out of work. Currently I am setting cancel = true when the work is complete but it seem not right. Any help appreciated.
If you use Task instead of manually creating threads, you can attach a continuation on your task to notify your UI that the work is complete.
Task workOne = Task.Factory.StartNew( () => ProcessThread1());
workOne.ContinueWith(t =>
{
// Update UI here
}, TaskScheduler.FromCurrentSynchronizationContext());
With .NET 4.5, this becomes even easier, as you can potentially use the new async language support:
var workOne = Task.Run(ProcessThread1);
var workTwo = Task.Run(ProcessThread2);
// asynchronously wait for both tasks to complete...
await Task.WhenAll(workOne, workTwo);
// Update UI here.
Note that these both are designed with a user interface in mind - and will behave unusually in a console application, as there is no current synchronization context in a console application. When you move this to a true user interface, it will behave correctly.
Start one more thread whose only job is to wait on console input:
private void ConsoleInputProc()
{
Console.Write("Press Enter to cancel:");
Console.ReadLine();
_cancellationTokenSource.Cancel();
}
Your main thread then starts the two processing threads and the input thread.
// create and start the processing threads
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.Start();
t2.Start();
// create and start the input thread
Thread inputThread = new Thread(ConsoleInputProc);
inputThread.Start();
Then, you wait on the two processing threads:
t1.Join();
// first thread finished. Request cancellation.
_cancellationTokenSource.Cancel();
t2.Join();
So if the user presses Enter, then the input thread sets the cancellation flags. thread1 and thread2 both see the cancellation request and exit.
If thread1 completes its work, then the main thread sets the cancellation flag and thread2 will cancel.
In either case, the program won't exit until thread 2 exits.
There's no need to kill the input thread explicitly. It will die when the program exits.
By the way, I would remove these lines from the thread 1 proc:
// I dont like this. Instead can I get notified in the UI thread that this thread is complete.
_cancel = true;
_cancellationTokenSource.Cancel();
I would remove the _cancel variable altogether, and have the first thread check IsCancellationRequested just like the second thread does.
It's unfortunate that you have to start a dedicated thread to wait on console input, but it's the only way I know of to accomplish this. The Windows console doesn't appear to have a waitable event.
Note that you could do this same thing with Task, which overall is easier to use. The code that the tasks perform would be the same.
Update
Looking at the bigger picture, I see that you have a typical producer/consumer setup with BlockingCollection. You can make your producer and consumer threads a lot cleaner:
private static void ProcessThread1()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Adding data..");
_samples.TryAdd(i, Timeout.Infinite, _cancellationTokenSource.Token);
// not sure why the sleep is here
Thread.Sleep(1000);
}
// Marks the queue as complete for adding.
// When the queue goes empty, the consumer will know that
// no more data is forthcoming.
_samples.CompleteAdding();
}
private static void ProcessThread2()
{
int data;
while (_samples.TryTake(out data, TimeSpan.Infinite, _cancellationTokenSource.Token))
{
// Do some work.
Console.WriteLine("Processing data..");
}
Console.WriteLine("Cancelled.");
}
You'll still need that input thread (unless you want to spin a loop on Console.KeyAvailable), but this greatly simplifies your producer and consumer.

Notify result from one thread to another or wait for feedback from the first thread to continue the second thread

I am trying to get 2 threads running in the background to perform tasks. I have to create the threads sequentially and proceed with the program execution. But the second thread must execute it's work only when the first finishes. Also, One more clarification. I am looking to have this solution on a WPF application. There is no UI feedback needed. All I need is a status update from the first task. I agree if we do all in one thread it will be fine. But we want to have the second thread which does more things seperately even if the user leaves the screen which created this thread.
Here is the sample:
class Program
{
static string outValue;
static bool _isFinished = false;
static void Main(string[] args)
{
ThreadStart thread1 = delegate()
{
outValue = AnotherClass.FirstLongRunningTask();
// I need to set the _isFinished after the long running finishes..
// I cant wait here because I need to kick start the next thread and move on.
//
};
new Thread(thread1).Start();
ThreadStart thread2 = delegate()
{
while (!_isFinished)
{
Thread.Sleep(1000);
Console.WriteLine("Inside the while loop...");
}
if (!string.IsNullOrEmpty(outValue))
{
// This should execute only if the _isFinished is true...
AnotherClass.SecondTask(outValue);
}
};
new Thread(thread2).Start();
for (int i = 0; i < 5000; i++)
{
Thread.Sleep(500);
Console.WriteLine("I have to work on this while thread 1 and thread 2 and doing something ...");
}
Console.ReadLine();
}
}
public class AnotherClass
{
public static string FirstLongRunningTask()
{
Thread.Sleep(6000);
return "From the first long running task...";
}
public static void SecondTask(string fromThread1)
{
Thread.Sleep(1000);
Console.WriteLine(fromThread1);
}
}
Where do I set the _isFinished?
I can't use BackgroundWorker threads. Any help is appreciated.
If a thread can only start when another one finishes, you have a very simple solution: execute the entire code on the first thread.
You can use Task.ContinueWith to queue up more work for the same Task.
You should simply call thread1.Join(), which will block until thread1 terminates.
However, there are a large number of better ways to do this.
You should use the TPL and the Task class instead.

what's wrong with my producer-consumer queue design?

I'm starting with the C# code example here. I'm trying to adapt it for a couple reasons: 1) in my scenario, all tasks will be put in the queue up-front before consumers will start, and 2) I wanted to abstract the worker into a separate class instead of having raw Thread members within the WorkerQueue class.
My queue doesn't seem to dispose of itself though, it just hangs, and when I break in Visual Studio it's stuck on the _th.Join() line for WorkerThread #1. Also, is there a better way to organize this? Something about exposing the WaitOne() and Join() methods seems wrong, but I couldn't think of an appropriate way to let the WorkerThread interact with the queue.
Also, an aside - if I call q.Start(#) at the top of the using block, only some of the threads every kick in (e.g. threads 1, 2, and 8 process every task). Why is this? Is it a race condition of some sort, or am I doing something wrong?
using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging;
using System.Threading;
using System.Linq;
namespace QueueTest
{
class Program
{
static void Main(string[] args)
{
using (WorkQueue q = new WorkQueue())
{
q.Finished += new Action(delegate { Console.WriteLine("All jobs finished"); });
Random r = new Random();
foreach (int i in Enumerable.Range(1, 10))
q.Enqueue(r.Next(100, 500));
Console.WriteLine("All jobs queued");
q.Start(8);
}
}
}
class WorkQueue : IDisposable
{
private Queue<int> _jobs = new Queue<int>();
private int _job_count;
private EventWaitHandle _wh = new AutoResetEvent(false);
private object _lock = new object();
private List<WorkerThread> _th;
public event Action Finished;
public WorkQueue()
{
}
public void Start(int num_threads)
{
_job_count = _jobs.Count;
_th = new List<WorkerThread>(num_threads);
foreach (int i in Enumerable.Range(1, num_threads))
{
_th.Add(new WorkerThread(i, this));
_th[_th.Count - 1].JobFinished += new Action<int>(WorkQueue_JobFinished);
}
}
void WorkQueue_JobFinished(int obj)
{
lock (_lock)
{
_job_count--;
if (_job_count == 0 && Finished != null)
Finished();
}
}
public void Enqueue(int job)
{
lock (_lock)
_jobs.Enqueue(job);
_wh.Set();
}
public void Dispose()
{
Enqueue(Int32.MinValue);
_th.ForEach(th => th.Join());
_wh.Close();
}
public int GetNextJob()
{
lock (_lock)
{
if (_jobs.Count > 0)
return _jobs.Dequeue();
else
return Int32.MinValue;
}
}
public void WaitOne()
{
_wh.WaitOne();
}
}
class WorkerThread
{
private Thread _th;
private WorkQueue _q;
private int _i;
public event Action<int> JobFinished;
public WorkerThread(int i, WorkQueue q)
{
_i = i;
_q = q;
_th = new Thread(DoWork);
_th.Start();
}
public void Join()
{
_th.Join();
}
private void DoWork()
{
while (true)
{
int job = _q.GetNextJob();
if (job != Int32.MinValue)
{
Console.WriteLine("Thread {0} Got job {1}", _i, job);
Thread.Sleep(job * 10); // in reality would to actual work here
if (JobFinished != null)
JobFinished(job);
}
else
{
Console.WriteLine("Thread {0} no job available", _i);
_q.WaitOne();
}
}
}
}
}
The worker threads are all blocking on the _q.WaitOne() call in DoWork(). Calling the thread's Join() method will deadlock, the threads never exit. You'll need to add a mechanism to signal to worker thread to exit. A ManualResetEvent, tested with WaitAny in the worker, will get the job done.
One debugging tip: get familiar with the Debug + Windows + Threads window. It lets you switch between threads and look at their call stacks. You'd have quickly found this problem by yourself.
You do a WaitOne() at the end of DoWork but you never set it after the threads start running.
Note that AutoResetEvent will go back to not set state after a 'successful' WaitOne
Your loop in your DoWork method never finishes. This will cause the thread to always be busy and this thread.Join() will block forever, waiting for it to complete.
You have a WaitOne, but I don't think it's necessary unless there is a reason you want your threadpool to stick around after your work is complete:
private void DoWork()
{
bool done = false;
while (!done)
{
int job = _q.GetNextJob();
if (job != Int32.MinValue)
{
Console.WriteLine("Thread {0} Got job {1}", _i, job);
Thread.Sleep(job * 10); // in reality would to actual work here
if (JobFinished != null)
JobFinished(job);
}
else
{
Console.WriteLine("Thread {0} no job available", _i);
done = true;
}
}
}
If you want the threads to stick around so you don't have to realloc more threads when WorkQueue.Start is called, you'd have to do something more elaborate with the AutoResetEvent.
Your main problem is the deterministic deadlock described in the other answers.
The correct way to handle it, though, is not to fix the deadlock, but to eliminate the Event altogether.
The whole idea of the Producer-Consumer model is that the clients En-queue and De-queue elements concurrently, and that's why sync mechanisms are required. If you're enqueuing all of the elements beforehand and then only dequeue concurrently, you only need a lock on the dequeue, since the "Event" is used to let "Consumers" wait for new elements to be enqueued; this will not happen in your case (based on your description).
Also, the "single responsibility" design principle suggests that the threading code should be separated from the "Blocking Queue" code. Make the "Blocking Queue" a class of its own, then use it in your thread-management class.

Categories