Using C# to create a windows service application. I have a main object that creates worker threads to periodically conduct various tasks. Each worker completes a specific task, waits for a time, then repeats.
If one of those tasks should fail, I want that thread to alert the main to log that a task failed and then to exit.
I had thought about using a ManualResetEvent where Set would be called from each worker (and main would loop on checking it). Problem is, multiple workers could fail simultaneously and attempt to Set() the event at the same time.
Is there a thread-safe way to handle alerting from multiple worker threads? Only one alert is required, I don't need to handle any more than the first one received.
Why don't use Double-checked locking in your Setter / Event handler?
private static readonly object Locker = new object();
private bool _closing = false;
private void YourErrorHandler(object sender, EventArgs args)
{
if(!_closing)
lock (Locker)
if(!_closing)
{
_closing = true;
//What ever you need to do here
}
}
If you need cross process sync, you will need to use Mutex or something else. But hope you get the idea
Once one of the threads fails, you want to shut down the whole thing, correct? Once that happens, when you join all of the threads, you can check their status and report an error for each individual one that failed. Something like:
while(eventNotSet) sleep();
foreach(thread)
{
thread.Join();
checkStatus(thread);
}
Related
I am considering creating an asynchronous logging component having a dedicated thread that will read new items from queue and write to database, file, etc. If I create a thread as a background one - it will be terminated as soon as the process ends thus all items in queue will be lost. If I create it is a foreground one - I will have to figure out when to stop it as it will prevent the application from closing. Is there any way not to make developers remember to 'stop' logging functionality before application exits?
I believe you can:
Subscribe to the AppDomain.ProcessExit event;
Use a Volatile sentinel variable as a shutdown flag;
Set the flag when the ProcessExit event fires up;
Monitor the state of the flag inside your thread, and gracefully shut down accordingly.
This way you may keep a foreground thread aware of impending doom.
First of all I have to agree with the comments above. I would just use something like NLog rather than trying to roll my own. While it may seem like there is a lot to learn at first, it is still better than writing and debugging your own.
If you really want to travel this road, my recommendation would be to use a 'using' statement and IDisposable to control the asynchronous behavior. Just start a normal thread in the ctor and signal & Join the thread on Dispose().
Example usage:
void Main()
{
using (new Logging())
{
...
}
}
Example class (untested):
class Logging :IDisposable
{
ManualResetEvent _stop = new ManualResetEvent(false);
Thread _worker = null;
public Logging()
{
_worker = new Thread(AsyncThread);
_worker.Start();
}
public void Dispose()
{
_stop.Set();
_worker.Join();
}
public void AsyncThread()
{
...
}
}
In your logging routine, you will want to test if the thread is running and then decide between queuing the log write or directly appending to the log output. This way log messages before and after the async thread will continue to work correctly.
I'm trying to make cross-threaded calls in C#.
Whenever I invoke the methods of an object created in the context of thread A from a static method called from thread B, the method always runs in thread B. I don't want that, I want it run on the same thread as the thread A object whose methods I am calling.
Invoke works fine for UI calls and I've read dozens of articles and SO answers relating to different ways of making cross-threaded Forms/WPF calls. However whatever I try (event handling, delegates, etc) Thread A's object's method will always run in Thread B if it is invoked by Thread B.
What part of the library should I be looking in to solve this? If it's relevant, Thread B currently 'spins', reads from a network port and occasionally invokes Thread A's object's method through a delegate that was created in Thread A and passed in using a ParameterizedThreadStart.
I'm not looking to change paradigm, just send a message (a request to invoke a method) from one thread (Thread B) to another (Thread A).
EDIT:
My question was 'what part of the library should I be looking in to solve this?' The answer appears to be none. If I want to clearly delineate consumption and polling I'll have to write my own code to handle that.
Whenever I invoke the methods of an object running on thread A
Objects don't run on threads.
In order for this to work, you will have to create some kind of queue you can shove a delegate into that will be routinely checked thread A's main loop. Something like this, assuming that Something.MainThreadLoop is the entry point for thread A:
public class Something
{
private Queue<Action> actionQueue = new Queue<Action>();
private volatile bool threadRunning = true;
public void RunOnThread(Action action)
{
if (action == null)
throw new ArgumentNullException("action");
lock (actionQueue)
actionQueue.Enqueue(action);
}
public void Stop()
{
threadRunning = false;
}
private void RunPendingActions()
{
while (actionQueue.Count > 0) {
Action action;
lock (actionQueue)
action = actionQueue.Dequeue();
action();
}
}
public void MainThreadLoop()
{
while (threadRunning) {
// Do the stuff you were already doing on this thread.
// Then, periodically...
RunPendingActions();
}
}
}
Then, given a reference to a Something object, you could do this:
something.RunOnThread(() => Console.WriteLine("I was printed from thread A!"));
Code runs on threads. Objects aren't (generally - see thread local) bound to a particular thread. By doing WinFormControl.Invoke or WPFControl.Invoke, you are posting a message to the Message Pump or Dispatcher respectively, to run some code at a later date.
The message pump is something like this:
Message message;
while(GetMessage(&message))
{
ProcessMessage(message);
}
Microsoft has specifically built their UI controls and projects to allow the posting of messages across threads. Calling a method from thread A will always execute that method on thread A, even if it ends up doing some kind of asynchronous work and returning early.
Edit:
What it is I think you need is the Producer Consumer pattern.
http://msdn.microsoft.com/en-us/library/yy12yx1f(VS.80).aspx
Forget about consuming the messages from your main thread, which is what it sounds like you want to do. Consume from thread C.
Thread A is doing 'much more important things'. Thread B is spinning, listening for messages. Thread C is consuming those messages.
No need for marshalling across threads.
EDIT: I think you probably want to use the System.Threading.AutoResetEvent class. The MSDN documentation has a decent example of one thread waiting on the other that I think is similar to what you are trying to do: http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
In particular, pay attention to the calls to trigger.WaitOne() and trigger.Set()
EDIT2: Added option #3 after reading new comment from OP.
"Whenever I invoke the methods of an object running on thread A ..." - An object doesn't "run" on a thread and isn't really owned by any thread, regardless of what thread created the object.
Given that your question is regarding "non-UI cross-thread invocation", I assume you are already familiar with "UI cross-thread invocation". I can see how WinForms would give you an impression that a thread owns an object and that you need to "send a message" to a thread in order to make it do something.
WinForm control objects are kind of a special case in that they simply don't function properly if you interact with them with a thread that isn't the one that created them, but that's not caused by the way that threads and objects interact.
Anyway, on to addressing your question.
First, a question to clarify the problem: You've mentioned what Thread B is doing, but what is Thread A doing prior to being "invoked" by Thread B?
Here are a couple of ideas that I think are along the lines of what you want to do:
Don't create Thread A until you need to. Instead of having Thread B "send a message to Thread A", rather have Thread B create Thread A (or call it Thread C if you prefer) and make it start executing at that time.
If you need Thread A to already exist and you only want Thread A to handle Thread B's events one at a time, you could have Thread A wait until it receives a notification from Thread B. Take a look at the System.Threading.WaitHandle class (derived classes of interest are ManualResetEvent and AutoResetEvent).
Thread A will at some point call WaitHandle.WaitOne(), which will cause it to pause and wait until Thread B calls WaitHandle.Set() on the same WaitHandle object.
If Thread A is busy doing other things, then you might want to set up some kind of flag variable. Similar to the WaitHandle concept in #2, but instead of causing Thread A to pause, you just want Thread B to set a flag (perhaps just a boolean variable) that will signal to Thread A that it needs to do something. While Thread A is busy doing other things, it can periodically check that flag to decide whether or not there is work that needs to be done.
Does the method that Thread A will execute on your object require any input from Thread B? Then before Thread B calls WaitHandle.Set(), have it stick some data into a queue or something. Then, when Thread A is "activated", it can retrieve that data from the queue and proceed to execute the object's method using that data. Use a lock mechanism (i.e. the C# lock statement) to synchronize access to the queue.
What you're going to have to do is roll a sort of Queue and have Thread A watch that queue for work. When Thread A sees new work enter the queue, it can dequeue it and do the work, then return to waiting for more.
Here's some pseudo-code:
public class ThreadAQueue
{
private Queue<delegate> _queue;
private bool _quitWorking;
public void EnqueueSomeWork(delegate work)
{
lock(_queue)
{
_queue.Enqueue(work);
}
}
private void DoTheWork()
{
while(!quitWorking)
{
delegate myWork;
lock(_queue)
{
if(_queue.Count > 1)
myWork = _queue.Dequeue();
}
myWork();
}
}
}
I have two working threads.I have locked both with a same lock, but threadB is getting executed before threadA, so exception came.I locked both using the same lock object.Thread B is using delegate function.How can I solve the issue.
Detailed Information:
I have a class called StateSimulation.
Inside that there are two functions called
a) OnSimulationCollisionReset
b) OnSimulationProgressEvent
Implementation is like this:
private void OnSimulationCollisionReset()
{
Thread XmlReset = new Thread(XmlResetFn);
XmlReset.Start();
}
private void OnSimulationProgressEvent()
{
DataStoreSingleTon.Instance.IsResetCompleted = true;
Thread ThrdSimulnProgress = new Thread(SimulnProgress);
ThrdSimulnProgress.Start();
}
where SimulnProgress() and XmlResetFn() are as follows:
private void SimulnProgress()
{
//uses a delegate
UIControlHandler.Instance.ShowSimulationProgress();
}
private void XmlResetFn()
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
In which OnSimulationProgressEvent() is using a delegate function.
Both showSimulationProgress and ResetXML...() uses a same resource FPBArrayList.
My requirement is SimulationProgressEvent() should work only after Reset..(). In resetXML..() I clear the FPBList.
In SimulationProgress() I access FPBList[i] where i:0--->size;
I have locked both functions using a same lock object.I expected, reset() will complete first. But after entering to reset, before complete reset, showProgress() started and exception occured..
How to solve my issue?
This is how I locked the functions
public System.Object lockThis = new System.Object();
private void SimulnProgress()
{
lock (lockThis)
{
UIControlHandler.Instance.ShowSimulationProgress();
}
}
private void XmlResetFn()
{
lock (lockThis)
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
}
Please give a solution.
Regards
Nidhin KR
It's not a good idea to write multithreaded code that assumes or requires that execution on different threads occurs in a particular order. The whole point of multithreading is to allow things to be executed independently of each other. Independently means no particular order is expressed or implied. CPU time might not be distributed evenly between the two threads, for example, particularly is one thread is waiting for an external signaling event and the other thread is in a compute loop.
For your particular code, it seems very odd that IsResetCompleted = true; is set in the OnSimulationProgressEvent handler. The completion state of the Reset activity should be set by the Reset activity, not by some other event executing in another thread assuming "If we're here, the work in the other thread must be finished."
You should review your design and identify your assumptions and dependencies between threads. If thread B must not proceed until after thread A has completed something, you should first reexamine why you're putting this work in different threads, and then perhaps use a synchronization object (such as an AutoResetEvent) to coordinate between the threads.
The key point here is if you take a sequential task and split it into multiple threads, but the threads use locks or synch objects to serialize their execution, then there is no benefit to using multiple threads. The operation is still sequential.
Locks are intended to prevent several threads from entering a given section of code simultaneously. They are not intended to synchronize the threads in any other way, like, making them execute code in some specific order.
To enforce the execution order you need to implement some signalling between your threads.
Have a look at Synchronization Primitives, specifically, Auto/ManualResetEvent is probably what you want.
I am not sure if I understand the question entirely, but if your requirement is simply that you want to prevent the body of SimulnProgress from executing before XmlResetfn has executed at least once, you can do:
public readonly object lockThis = new object();
private readonly ManualResetEvent resetHandle = new ManualResetEvent(false);
private void SimulnProgress()
{
resetHandle.WaitOne();
lock (lockThis)
{
UIControlHandler.Instance.ShowSimulationProgress();
}
}
private void XmlResetFn()
{
lock (lockThis)
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
resetHandle.Set();
}
I'm trying to write a ThreadManager for my C# application. I create several threads:
One thread for my text writer.
One thread that monitors some statistics.
Multiple threads to perform a large sequence of calculations (up to 4 threads per core and I run my app on a 2x quad core server).
My application normally runs for up to 24 hours at a time, so all the threads get created in the beginning and they persist through the entire time the app runs.
I want to have a single place where I "register" all of my treads and when the application is shutting down I simply invoke a method and it goes through all of the registered threads and shuts them down.
For that purpose I have devised the following class:
public class ThreadManager
{
private static Object _sync = new Object();
private static ThreadManager _instance = null;
private static List<Thread> _threads;
private ThreadManager()
{
_threads = new List<Thread>();
}
public static ThreadManager Instance
{
get
{
lock (_sync)
{
if (_instance == null)
{
_instance = new ThreadManager();
}
}
return _instance;
}
}
public void AddThread(Thread t)
{
lock (_sync)
{
_threads.Add(t);
}
}
public void Shutdown()
{
lock (_sync)
{
foreach (Thread t in _threads)
{
t.Abort(); // does this also abort threads that are currently blocking?
}
}
}
}
I want to ensure that all of my threads are killed so the application can close properly and shutting down in the middle of some computation is just fine too. Should I be aware of anything here? Is this approach good given my situation?
If you set the threads to background threads, they will be killed when the application is shut down.
myThread.IsBackground = true;
obviously if you need the threads to finish before shutdown, this is not the solution you want.
Aborting threads is what you do when all else fails. It is a dangerous thing to do which you should only do as a last resort. The correct way to do this is to make your threading logic so that every worker thread responds quickly and correctly when the main thread gives it the command to shut itself down.
Coincidentally, this is the subject of my blog this week.
http://blogs.msdn.com/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx
What if AddThread is called while your Shutdown is running?
When shutdown finishes, the thread waiting in AddThread will add a new thread to the collection. This could lead to hangs in your app.
Add a bool flag that you ever only set in Shutdown to protect against this.
bool shouldGoAway = false;
public void AddThread(Thread t)
{
lock (_sync)
{
if( ! shouldGoAway )
_threads.Add(t);
}
}
public void Shutdown()
{
lock (_sync)
{
shouldGoAway = true;
foreach (Thread t in _threads)
{
t.Abort(); // does this also abort threads that are currently blocking?
}
}
Also you should not use static members - there is no reason for that as you have your Singleton instance.
.Abort() does not abort threads that are blocking in unmanaged space. So if you do that you need to use some other mechanism.
The only specific issue I know about is this one: http://www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx
But I'd avoid having to resort to a design like this. You could force each of your threads to check some flag regularly that it's time to shut down, and when shutting down, set that flag and wait for all threads to finish (with Join()). It feels a bit more like controlled shutdown that way.
If you don't care about the worker thread state then you can loop through _thread and abort:
void DieDieDie()
{
foreach (Thread thread in _thread)
{
thread.Abort();
thread.Join(); // if you need to wait for the thread to die
}
}
In your case you can probably just abort them all and shutdown as they're just doing calculations. But if you need to wait for a database write operation or need to close an unmanaged resource then you either need to catch the ThreadAbortException or signal the threads to kill themselves gracefully.
You want deferred thread cancellation, which basically means that the threads terminate themselves as opposed to a thread manager cancelling threads asynchronously, which is much more ill-defined and dangerous.
I you wanted to handle thread cancellation more elegantly than immediate termination, you can use signal handlers that are triggered by events outside the thread - by your thread manager perhaps.
I'm looking for a way to restart a thread that has been stopped by Abort()..
public partial class MyProgram : Form
{
private Thread MyThread = new Thread(MyFunction);
private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button();
public MyProgram()
{
MyThread.Start();
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
private static void MyFunction()
{
// do something
}
private void doStop(object sender, EventArgs e)
{
MyThread.Abort();
startStopBtn -= new EventHandler(doStop);
startStopBtn += new EventHandler(doStart);
startStopBtn.Text = "Start";
}
private void doStart(object sender, EventArgs e)
{
MyThread.Start(); // << Error returned when clicking the button for 2nd time
startStopBtn -= new EventHandler(doStart);
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
}
Any idea?
Once you have aborted your thread, you cannot start it again.
But your actual problem is that you are aborting your thread. You should never use Thread.Abort().
If your thread should be paused and continued several times, you should consider using other mechanisms (like AutoResetEvent, for example).
[EDIT]
The simplest solution to abort a thread, as mentioned by Ian Griffiths in the link above, is:
The approach I always recommend is dead simple. Have a volatile bool field that is visible both to your worker thread and your UI thread. If the user clicks cancel, set this flag. Meanwhile, on your worker thread, test the flag from time to time. If you see it get set, stop what you're doing.
The only thing that you need to do to make it work properly, is to rearrange your background method so that it runs in a loop - so that you can periodically check if your flag has been set by a different thread.
If you need to have pause and resume functionality for the same worker thread, instead of the simple volatile bool flag approach, you could go for a slightly more complex approach, a synchronizing construct such as AutoResetEvent. These classes also provide a way to put the worker thread to sleep for a specified (or indefinite) amount of time between signals from the non-worker thread.
This thread contains a concrete example with Start, Pause, Resume and Stop methods. Note how Brannon's example never aborts the thread. It only fires an event, and then waits until the thread finishes gracefully.
Simply add MyThread = new Thread(MyFunction) before calling MyThread.Start() in doStart(). Do not create the thread outside of your methods, the space there is thought for declarations.
Please note that killing a thread with thread.Abort() can be very dangerous, as it might cause unexpected behavior or might not correctly dispose resources owned by the thread. You should try to accomplish clean multi threading, like Groo described in his answer.
The simple answer is, you can't. Once a thread has been aborted, you can't restart it. Just create a method or something, that returns a Thread object just how you need it. When you need a new Thread, just get it from that method.
No, there isn't, but why would you want to? Just start up a new thread, with the same ThreadStart, and the same parameter (if any).
If you really need to interrupt the thread function and resume, you should set a condition and then check it periodically during processing.
That would allow you to stop processing for some amount of time and then resume.
I've used events and Wait calls to accomplish a similar task.
The easiest way is to not abort the thread.
I really don't understand why people provide information if they do not know that is correct..
How can a real programmer suspend or stop processing a thread for sometime and then release it and thereby making the code vulnerable...
#Brad-- m sorry.. but your idea was not good..
#Rhythmic - You need to work on your way to approach things..
BFree was somewhat right if you people got him the same way he wanted to say..
You just need to re-declare that..
below is the example:
Public Shared Sub ResetAbort()
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
Thread.Sleep(2000)
YourThreadName.Abort()
End Sub
Now you can use this Sub anywhere you want to start the thread. It will automatically abort the thread.
If you want to start the thread on Button1_click() event and stop it on Button2_Click() event use this:
in Button1_click() event
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
in Button2_click() event
YourThreadName.Start()
doing this way you will abort you thread where ever you want and will initialize it again.
You can also use YourThreadName.ThreadState.Running property to check if the thread is running or not(Just to avoid multiple instances of the same thread.....