Worker thread and Dipose() - c#

I have some utility class with worker thread with simple exit condition. I use this class in my application. Worker thread is created and started in class constructor.
class MyClass
{
Thread _thread;
// unrelevant details are omitted
void WorkerThreadRoutine
{
while(_running)
{
// do some useful background work here
}
}
}
My question is WHEN do I have to set _running=false. In C++ with deterministic
resource deallocation life is easy - I use object destructors and don't care.
I would write something like
~MyClass()
{
_running = false;
}
In C# there no destructors in C++ sense. Do I have to write some Dispose() function here
and use IDisposable? I can of course provide a Stop() function. But when do I have to call it? Is there a way to automatically have my Stop function called?
What is right pattern here? I have lots of MyClass intances across my application.
Right now my application hangs on exit.

The reason your application hangs is that new threads are created as foreground threads per default. The CLR will keep your process alive as long as you have any running foreground threads.
To get rid of the thread, just exit the code it is running. This will make the thread available for cleanup and once it has shut down the process will be able to close as well (assuming you have no other foreground threads running).

In C++, you'd normally explicitly call the delete operator. That's not different from explicitly calling a Stop() method in C#.
The C++ compiler can auto-generate the delete operator call if your object is a local variable of a method. That maps well to IDisposible in C# with the using statement:
void SomethingSlow() {
using (var obj = new MyClass()) {
// etc..
}
}
class MyClass : IDisposable {
private ManualResetEvent mStop = new ManualResetEvent(false);
public Dispose() {
mStop.Set();
}
// etc...
}
Your thread probably doesn't stop right now because you forgot to declare the _running field as volatile. Using an event can help avoid problems like that. You can set the thread's IsBackground property to true to prevent the thread from hanging your program termination. That's a band-aid, not a fix.

Related

Releasing a named mutex created in WPF Application.OnStartUp(): Which thread owns it?

I create a mutex within the OnStartup Method of a WPF app. The mutex is not used anywhere else in the program, its only purpose is to prevent certain programs from running concurrently. How can I release this mutex when the application closes?
According to the documentation, mutex.ReleaseMutex() must be called from the same thread that created the mutex. However this presents a problem, since I do not control the thread that calls OnStartup().
Suppose my OnStartup method looks like this:
public partial class App : Application
{
private Mutex mutex;
private bool hasHandle = false;
protected override void OnStartup(StartupEventArgs e)
{
bool createdNew;
mutex = new Mutex(false, #"Global\XYZ", out createdNew);
try
{
hasHandle = mutex.WaitOne(5000, false);
if (!hasHandle)
{/*do stuff*/};
}
catch (AbandonedMutexException)
{
hasHandle = true;
// do stuff
}
base.OnStartup(e);
}
private void releaseMutex()
{
if (mutex!=null)
{
if (hasHandle) mutex.ReleaseMutex();
mutex.Dispose();
}
}
}
Is it save to call releaseMutex() ...
in the OnExit() method?
protected override void OnExit(){releaseMutex();}
in the ProcessExit event handler?
AppDomain.CurrentDomain.ProcessExit += (sender,e)=> releaseMutex();
in a finalizer?
~App(){releaseMutex();}
in the unhandled exception event handler?
AppDomain.CurrentDomain.UnhandledException += (sender,e)=> releaseMutex();
It seems like the OnExit method has the best chance to be in the same thread, but even that seems a sketchy assumption. Is there a way to ignore the same-thread requirement? Or should I create and store a separate thread in conjunction with my mutex?
I personally wouldn't bother releasing it at all, especially since you handle AbandonedMutexException.
If a mutex is not used to synchronize threads of the same process there is no need to explicitly release it. When a process terminates OS automatically closes all handles created by the process, such as files, sockets, mutexes, semaphores and event handles .
If you still prefer to release it consider using Application.OnExit() since it is called from the main thread, just like the Startup().
According to my research, every GUI WPF application has a UI thread which can be accessed via Application.Current.Dispatcher (see for example this answer). This UI thread should always remain active for the lifetime of the application.
You can use Dispatcher.CheckAccess to see whether you are running in the UI thread, and if you are not you can use Dispatcher.Invoke to execute an action in the context of the UI thread.
The description of Application.Run implies that Application.OnStartup is always run on the UI thread, but it should not be harmful to check and, if necessary, use the UI thread dispatcher to invoke the action that creates the mutex.
It seems a reasonable guess that Application.OnExit is also always run on the UI thread, but since this does not appear to be documented, you should check and, if necessary, use the UI thread dispatcher to invoke the action that releases the mutex.
As Alexm correctly points out, you do not in fact need to explicitly release the mutex provided that the application is running in its own process (which will usually be the case) but you do need to ensure that the thread the mutex is created on will remain active until you are ready to free it. I believe using the UI thread is the simplest way to ensure this.

closing WPF Window does not start destruction

Assume following scenario:
There is a WPF window, within a MVVM implementation. Having following code in it's code behind file (acutally I know I rather should use ViewModel first approach, but using View First is enough at this stage):
public MainWindow()
{
InitializeComponent();
this.DataContext = MainWindowViewModel.GetInstance();
}
within the constructor of
ClassStartingWorkerThread instance;
MainWindowViewModel()
{
instance = new ClassStartingWorkerThread();
}
I initialize an instance of a class which starts a Thread on construction like shown below:
ClassStartingWorkerThread()
{
StartThread();
}
private Thread mEventRequestingThread = null;
private void StartThread()
{
ThreadStart cDelegate = new ThreadStart(EventListening);
mEventRequestingThread = new Thread(cDelegate);
mEventRequestingThread.Start();
}
This class implements the IDisposable interface.
Therefore I call my Dispose method manually on Destruction like this:
~ClassStartingWorkerThread()
{
Dispose(false);
}
public void Dispose()
{
mEventRequestingThread.Abort();
}
At least you shall know: I start my application from Visual Studio.
Now, I'm closing my UI Window and would expect my routine to destruct created objects.
But the the Visual Studio does not go back into "edit" mode and stays in "debug" mode.
I guess there's something wrong with my thread routine, but I'm wondering why neither the MainWindow destructor nor the MainWindowViewModel destructor is called.
This leads to the question on how I can manually start the destruction routine and tell my worker thread, which actually seems to block this, to stop?
Thanks in advance,
Thomas
The problem is that your destructor ~ClassStartingWorkerThread() is never called by the garbage collector. The instance of that class cannot be garbage-collected since the executing thread references it via the ThreadStart delegate. Generally you should never rely on a destructor beeing called at all. See the MSDN on C# Destructors.
In your case simply set the Thread.IsBackground property to true. This will make the thread terminate automatically when the application shuts down.
If you really have to have manual control over the termination of your worker thread, you shouldn't abort it, but instead let it wait for (or cyclically check) some WaitHandle and terminate itself when the WaitHandle is signalled. When it comes to termination, Set the WaitHandle in your main thread, perhaps in a Window.Closing event handler.
I agree with Clemens' answer.
Just two points:
Delete your thread in a closewindow event. I don't know the names of events in WPF, but there must be one which is called when closing the window. Use it.
When deleting threads, you should always prefer some other methods than Abort(). Send a signal to that thread to let it be informed that window is about to be closed and let the thread peacefully ends its execution on its own.

Best way to report thread progress

I have a program that uses threads to perform time-consuming processes sequentially. I want to be able to monitor the progress of each thread similar to the way that the BackgroundWorker.ReportProgress/ProgressChanged model does. I can't use ThreadPool or BackgroundWorker due to other constraints I'm under. What is the best way to allow/expose this functionality. Overload the Thread class and add a property/event? Another more-elegant solution?
Overload the Thread class and add a
property/event?
If by "overload" you actually mean inherit then no. The Thread is sealed so it cannot be inherited which means you will not be able to add any properties or events to it.
Another more-elegant solution?
Create a class that encapsulates the logic that will be executed by the thread. Add a property or event (or both) which can be used to obtain progress information from it.
public class Worker
{
private Thread m_Thread = new Thread(Run);
public event EventHandler<ProgressEventArgs> Progress;
public void Start()
{
m_Thread.Start();
}
private void Run()
{
while (true)
{
// Do some work.
OnProgress(new ProgressEventArgs(...));
// Do some work.
}
}
private void OnProgress(ProgressEventArgs args)
{
// Get a copy of the multicast delegate so that we can do the
// null check and invocation safely. This works because delegates are
// immutable. Remember to create a memory barrier so that a fresh read
// of the delegate occurs everytime. This is done via a simple lock below.
EventHandler<ProgressEventArgs> local;
lock (this)
{
var local = Progress;
}
if (local != null)
{
local(this, args);
}
}
}
Update:
Let me be a little more clear on why a memory barrier is necessary in this situation. The barrier prevents the read from being moved before other instructions. The most likely optimization is not from the CPU, but from the JIT compiler "lifting" the read of Progress outside of the while loop. This movement gives the impression of "stale" reads. Here is a semi-realistic demonstration of the problem.
class Program
{
static event EventHandler Progress;
static void Main(string[] args)
{
var thread = new Thread(
() =>
{
var local = GetEvent();
while (local == null)
{
local = GetEvent();
}
});
thread.Start();
Thread.Sleep(1000);
Progress += (s, a) => { Console.WriteLine("Progress"); };
thread.Join();
Console.WriteLine("Stopped");
Console.ReadLine();
}
static EventHandler GetEvent()
{
//Thread.MemoryBarrier();
var local = Progress;
return local;
}
}
It is imperative that a Release build is ran without the vshost process. Either one will disable the optimization that manifest the bug (I believe this is not reproducable in framework version 1.0 and 1.1 as well due to their more primitive optimizations). The bug is that "Stopped" is never displayed even though it clearly should be. Now, uncomment the call to Thread.MemoryBarrier and notice the change in behavior. Also keep in mind that even the most subtle changes to the structure of this code currently inhibit the compiler's ability to make the optimization in question. One such change would be to actually invoke the delegate. In other words you cannot currently reproduce the stale read problem using the null check followed by an invocation pattern, but there is nothing in the CLI specification (that I am aware of anyway) that prohibits a future hypothetical JIT compiler from reapplying that "lifting" optimization.
I tried this some time ago and it worked for me.
Create a List-like class with locks.
Have your threads add data to an instance of the class you created.
Place a timer in your Form or wherever you want to record the log/progress.
Write code in the Timer.Tick event to read the messages the threads output.
You might also want to check out the Event-based Asynchronous Pattern.
Provide each thread with a callback that returns a status object. You can use the thread's ManagedThreadId to keep track of separate threads, such as using it as a key to a Dictionary<int, object>. You can invoke the callback from numerous places in the thread's processing loop or call it from a timer fired from within the thread.
You can also use the return argument on a callback to signal the thread to pause or halt.
I've used callbacks with great success.

Compact Framework 2.0: How can I stop a thread when an object is dispose?

I have this code:
Thread t = new Thread(() => UpdateImage(origin));
t.Name = "UpdateImageThread";
t.Start();
This code is created on a Custom Control. I want to stop this thread (if it's running) when the object is going to be dispose.
This custom control has the following method:
void IDisposable.Dispose()
{
/* My own code */
base.Dispose(true);
}
I think this is the place to put the code but:
How can I know is the thread is running?
How can I take a referece for the thread and stop it?
By the way, UpdateImage call a web service, so I think that it's waiting all of its life.
How can I finish this wait?
Thank you!
It depends a lot on what UpdateImage() does and how well it copes with the Image being disposed while it it still active. If UpdateImage() is your code and contains a loop you can tell it to stop (using a field like _stopping). If not, the best thing may be to do nothing - in the rare case of Disposing the control while the image is still updating you take the penalty of leaving it to the GC.
About how to get the Thread: By saving the reference when and where you create it, for instance int the private member _updateThread.
Now actually stopping (aborting) the thread is a (very) bad idea.
So you'll need an indicator, like
private bool _stopping = false;
And it is up to the UpdateImage() method to react to _stopping == true and stop with what it is doing.
Your Dispose() can then use
_stopping = true;
_updateThread.Join()
Save your thread variable 't' so that you can re-use it later.
Within your Dispose method you want something like:
void IDisposable.Dispose()
{
if(t.IsRunning)
{
cancelThreads = true; // Set some cancel signal that the thread should check to determine the end
t.Join(500); // wait for the thread to tidy itself up
t.Abort(); // abort the thread if its not finished
}
base.Dispose(true);
}
You should be careful aborting threads though, ensure that you place critical section of code within regions that won't allow the thread to stop before it has finished, and catch ThreadAbortExceptions to tidy anything up if it is aborted.
You can do something like this in the threads start method
public void DoWork()
{
try
{
while(!cancelThreads)
{
// Do general work
Thread.BeginCriticalRegion();
// Do Important Work
Thread.EndCriticalRegion();
}
}
catch(ThreadAbortException)
{
// Tidy any nastiness that occured killing thread early
}
}
I suggest to override the Dispose method in your Custom Control.
There you have the reference of your thread and you can call .Join() for example...

Proper way to clean up a permanent thread in C#

I have an object, a Timeline, that encapsulates a thread. Events can be scheduled on the timeline; the thread will wait until it is time to execute any event, execute it, and go back to sleep (for either (a) the time it takes to get to the next event or (b) indefinitely if there are no more events).
The sleeping is handled with a WaitEventHandle, which is triggered when the list of event is altered (because the sleep delay may need to be adjusted) or when the thread should be stopped (so the thread can terminate gracefully).
The destructor calls Stop(), and I've even implemented IDisposable and Dispose() also calls Stop().
Still, when I use this component in a forms application, my application will never shut down properly when I close the form. For some reason, Stop() is never called, so neither my object's destructor triggers, nor is the Dispose() method called, before .NET decides to wait for all threads to finish.
I suppose the solution would be to explicitly call Dispose() myself on the FormClose event, but since this class is going to be in a library, and it is actually a layer deeper (that is, the application developer will never actually see the Timeline class), this seems very ugly and an extra (unnecessary) gotcha for the application developer. The using() clause, which I would normally use when resource release becomes an issue, doesn't apply as this is going to be a long-lived object.
On the one hand, I can understand that .NET will want to wait for all threads to finish before it does its final round of garbage collection, but in this case that produces a very clumsy situation.
How can I make my thread clean up after itself properly without adding requirements to consumers of my library? Put another way, how can I make .NET notify my object when the application is exiting, but before it will wait for all threads to finish?
EDIT: In response to the people saying that it is ok for the client program to be aware of the thread: I respectfully disagree.
As I said in my original post, the thread is hidden away in another object (an Animator). I instantiate an Animator for another object, and I tell it to perform animations, such as "blink this light for 800ms".
As a consumer of the Animator object, I do not care how the Animator makes sure that the light blinks for exactly 800ms. Does it start a thread? I don't care. Does it create a hidden window and use system timers (ew)? I don't care. Does it hire midgets to turn my light on and off? I don't care.
And I especially don't want to have to care that if I ever create an Animator, I have to keep track of it and call a special method when my program exits, in contrast to every other object. It should be a concern of the library implementor, not the library consumer.
EDIT: The code is actually short enough to show. I'll include it for reference, sans methods that add events to the list:
internal class Timeline : IDisposable {
private Thread eventThread;
private volatile bool active;
private SortedList<DateTime, MethodInvoker> events = new SortedList<DateTime,MethodInvoker>();
private EventWaitHandle wakeup = new EventWaitHandle(false, EventResetMode.AutoReset);
internal Timeline() {
active = true;
eventThread = new Thread(executeEvents);
eventThread.Start();
}
~Timeline() {
Dispose();
}
private DateTime NextEvent {
get {
lock(events)
return events.Keys[0];
}
}
private void executeEvents() {
while (active) {
// Process all events that are due
while (events.Count > 0 && NextEvent <= DateTime.Now) {
lock(events) {
events.Values[0]();
events.RemoveAt(0);
}
}
// Wait for the next event, or until one is scheduled
if (events.Count > 0)
wakeup.WaitOne((int)(NextEvent - DateTime.Now).TotalMilliseconds);
else
wakeup.WaitOne();
}
}
internal void Stop() {
active = false;
wakeup.Set();
}
public void Dispose() {
Stop();
}
}
Maybe set the Thread.IsBackground property to true?
eventThread = new Thread(executeEvents);
eventThread.IsBackground = true;
eventThread.Start();
Another option is to use the Interrupt method to wake it up. Just make sure that you catch the ThreadInterruptedException in the thread that you are interrupting, and that it shuts down when it happens.
active = false;
eventThread.Interrupt();
try { eventThread.Join(); } // Wait for graceful shutdown
catch (Exception) { }
Not quite sure how that EventWaitHandle of yours works though... When I did something similar once, I just used the regular Thread.Sleep =)
I don't think it is unreasonable to require clients to Stop() the thread for shutdown at all. There are ways you can create threads whose continued execution will not stop the application from exiting (although I don't have the details off the top of my head). But expecting to launch and terminate a worker thread is not too much of a burden for the client.
There is no way to get .NET to notify your thread without the clients cooperation. If you're designing your library to have a long running background thread, then the client app has to be designed to know about it.
Application::ApplicationExit is a static event, is it acceptable to listen for it and do your special cleanup work?
Implementing IDisposable should be enough indication that your clients should be using your class in a "using" block.
Implement IDisposable properly, including implementing a finaliser that calls Dispose(true). You Animator object can then do any clean up it wishes to, including stopping the thread if necessary.

Categories