Mutex and Windows Phone 8.1 Silverlight - c#

I want to prevent my Background Process from performing an action if the app is open in the foreground. I found a similar question posed here, but I can't get it to work for me. When my Background Process checks the Mutex, it is never already in existence. When the foreground app starts I create a Mutex like so:
public void Application_Launching(object sender, LaunchingEventArgs e)
{
var myMutex = new Mutex(false, "MUTEX_NAME");
}
I release it when the foreground app closes:
private void Application_Closing(object sender, ClosingEventArgs e)
{
var myMutex = new Mutex(false, "MUTEX_NAME");
myMutex.ReleaseMutex();
}
In the Background Process I have the following check:
bool IsMutexLocked()
{
var myMutex = new Mutex(false, "MUTEX_NAME");
return myMutex.WaitOne(100);
}
I'm assuming here that WaitOne returns true if "MUTEX_NAME" doesn't exist, or it does exist but gets released after 100ms. I've also tried using the out createdNew in the Mutex constructor, and the static methods OpenExistingand TryOpenExisting but to no avail.

You are not locking your mutex in main app, you just create it (also without ownership). You can either create Mutex with initial ownership or call WaitOne() when needed. Some more help at Joe Alabhari's blog.
public void Application_Launching(object sender, LaunchingEventArgs e)
{
var myMutex = new Mutex(true, "MUTEX_NAME");
// or call myMutex.WaitOne() // here maybe some timeout handling
}
Also I don't think that holding a mutex until the app is closed is a good practise - lock the mutex only when you really need to (for example access to common file). If you really want to try this, create a global mutex instance upon launching, then release it upon closing, but without obtaining it again, just use previous instance.
Look out for couple of things - don't leave abandoned mutexes, look out so it's not garbage collected, release it when needed. There are plenty of posts about this synchronization object, here you have a good pattern.

Related

Mutex - TryOpenExisting vs new one

I'm thinking about Mutexes and I need some clarification about them. Should I try to open existing Mutex or create new one (of course both with the same name). Example of code:
First attempt - try open existing one:
private void AttemptOne()
{
Mutex myMutex;
if (!Mutex.TryOpenExisting("Mutex Name", out myMutex))
myMutex = new Mutex(false, "Mutex Name");
try
{
myMutex.WaitOne(3000);
// code
}
catch { }
finally
{
myMutex.ReleaseMutex();
// myMutex.Dispose(); - should I call that or it will be called automatically when returning from method?
}
}
Second attempt - create new Mutex:
private void AttemptTwo()
{
using (Mutex mutex = new Mutex(false, "Mutex Name"))
{
try
{
mutex.WaitOne(3000);
// code
}
catch { }
finally { myMutex.ReleaseMutex(); }
}
}
I have some questions, which bother me:
which attempt to use?
Let assume that I have a background process with created Mutex, and at the same time Main process tries to do some work, which should be blocked until backgorund process finishes. If background process created its own Mutex, should I try to open it?
Or create new Mutex in Main thread with the same name?
What is the difference between those attempts?
should I call Dispose() in first Attempt?
Or just assume that Mutex will be disposed when method returns? Will it be disposed then?
I assume that in second attempt Mutex will be Disposed (as its IDisposable) when using() ends. Am I right?
If you're planning to create the mutex if it doesn't exist anyway, then just go ahead and use the second method.
If you're going for a different behavior based on the existence of the mutex, then you should use TryOpenExisting to check if it exists.
As for your other questions:
Yes, you should call the Dispose or Close method on the mutex when you're done with it. In order to allow the operating system to destroy it once it's not in use.
Yes, using would call the Mutex object Dispose method.
I think you shouldn't use named mutex to synchronize threads in a single process. It's better to share a mutex (or semaphore) object between this threads (in a local variable or in a class field for example). So use named mutex to make process synchronization(for example running only one copy of the application).
About your questions. TryOpenExisting() represent a common pattern TryXxx and provide you opportunity to check the result of an operation without exceptions. Although there are some constructor overloads that have out createdNew boolean parameter you must declare another variable for this what is ugly. Your second variant means that you don't care about whether you have existing mutex or just create a new.
Calling Dispose() (or put the object into using) is always usefull practice. If you use named mutex like in your code all will be fine after disposing. But if you dispose a shared mutex variable (like I advice) in one thread all other threads which waits this mutex will fall with an exception. In this case you should dispose mutex only when you realy sure that you have no needs in it.
As you can see answers on your questions depends on the specific situation.

How to exit all running threads?

The following code does not exit the application. How can I exit the application and make sure all the running threads are closed?
foreach (Form form in Application.OpenForms)
{
form.Close();
}
Application.Exit();
You don't show the use of any threads in your code, but let's suppose you do have threads in it. To close all your threads you should set all of them to background threads before you start them, then they will be closed automatically when the application exits, e.g.:
Thread myThread = new Thread(...);
myThread.IsBackground = true; // <-- Set your thread to background
myThread.Start(...);
A "HOWTO: Stop Multiple Threads" article from microsoft: http://msdn.microsoft.com/en-us/library/aa457093.aspx
You can try the following code:
Environment.Exit(Environment.ExitCode);
I went through a similar issue in my software, but unfortunately just making the threads to work in background didn't solve the issue. In fact while the thread brings back data (the main software is data driven) and if I close the application, it results to Windows Error, giving rise to a debugging message.
So what actually worked for me:
Step 1: Made all threads run in background such as
Thread aThread = new Thread(MethodName);
aThread.IsBackground = true; //<-- Set the thread to work in background
aThread.Start();
Step 2: In the closing action of the form/application call the Environment.Exit method, such as
Environment.Exit(Environment.ExitCode);
This kept the memory managed perfectly, with no memory leak.
Hope this helps.
This should work for all threads you opened.
protected override void OnExiting(Object sender, EventArgs args)
{
base.OnExiting(sender, args);
Environment.Exit(Environment.ExitCode);
}
This is the best way to make sure that your application closes (forcefully):
(Process.GetCurrentProcess()).Kill()
The problem with Environment.Exit is that it does not work unless it is on the main thread. Also, it sometimes thread locks.
The main reason that your program is not closing properly is because the form is not able to dispose itself (and thus all object that it created). Fixing this is much more difficult. I would recommend running the above code after waiting a while for any possible dispose handlers to get called first.
This got the job done for me:
Instead of using:
Application.Exit()
which leaves other threads open, try using:
Environment.Exit(Environment.ExitCode);
I puzzled with this for a while as the common answer is to make the threads you call mythread.IsBackground = true;
The common answer to run a thread is to use a while loop with a flag
while(!exitflag)
{
// thread running
}
When User presses the eXit forms button Visual studio still is running the threads but the form closes. I used the Form Closing event to set the exitcode flag and then wait for the threads to close.
I have a single form using a Timer and two additional threads, One collects streaming data and the other does calculations on that data and saves to an sql table. Data collection is collected in a circular buffer. I use two static bool values as flags where the threads set the flag to true or false using mythread.Isalive as the Form Closing event does not have access to the thread handles.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Debug.WriteLine("Form Closing Event");
exitFlag = true;
int ThreadsClosed = 0;
while (ThreadsClosed < 2)
{
ThreadsClosed = 2;
if (ProcessDataAlive) ThreadsClosed = 0;
if (StreamingDataAlive) ThreadsClosed = 0;
Application.DoEvents();
}
Debug.WriteLine("Threads are all closed");
Thread.Sleep(5000); // allow debug window open to read remove for release
}

Multi-threading calls in Windows Forms application?

I'm trying to make my C# application multi threaded because sometimes, I get an exception that says I have made a call to a thread in an unsafe manner. I've never done any multi-threading before in a program, so bear with me if I sound kinda ignorant on the issue.
The overview of my program is that I want to make a performance monitoring applicaiton. What this entails is using the process and performance counter class in C# to launch and monitor an application's processor time, and sending that number back to the UI. However, in the method that actually calls the performance counter's nextValue method (which is set to perform every second thanks to a timer), I would sometimes get the aforementioned exception that would talk about calling a thread in an unsafe manner.
I've attached some of the code for your perusal. I know this is kind of a time consuming question, so I'd be really grateful if anyone could offer me any help as to where to make a new thread and how to call it in a safe way. I tried looking at what was up on MSDN, but that just kinda confused me.
private void runBtn_Click(object sender, EventArgs e)
{
// this is called when the user tells the program to launch the desired program and
// monitor it's CPU usage.
// sets up the process and performance counter
m.runAndMonitorApplication();
// Create a new timer that runs every second, and gets CPU readings.
crntTimer = new System.Timers.Timer();
crntTimer.Interval = 1000;
crntTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
crntTimer.Enabled = true;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
// get the current processor time reading
float cpuReading = m.getCPUValue();
// update the current cpu label
crntreadingslbl.Text = cpuReading.ToString(); //
}
// runs the application
public void runAndMonitorApplication()
{
p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = fileName;
p.Start();
pc = new System.Diagnostics.PerformanceCounter("Process",
"% Processor Time",
p.ProcessName,
true);
}
// This returns the current percentage of CPU utilization for the process
public float getCPUValue()
{
float usage = pc.NextValue();
return usage;
}
Check out Jon Skeet's article on multi-threading, particularly the page on multi-threading winforms. It should fix you right up.
Basically you need to check to see if an invoke is required, and then perform the invoke if needed. After reading the article you should be able to refactor your UI-updating code into blocks that look like this:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
// get the current processor time reading
float cpuReading = m.getCPUValue();
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new Action(() => crntreadingslbl.Text = cpuReading.ToString()));
return;
}
// Must be on the UI thread if we've got this far
crntreadingslbl.Text = cpuReading.ToString();
}
In your code, an invoke will be required because you are using a Timer. According to the documentation for System.Timers.Timer:
The Elapsed event is raised on a ThreadPool thread.
This means that the OnTimedEvent() method that you set as the Timer's delegate will execute on the next available ThreadPool thread, which will definitely not be your UI thread. The documentation also suggests an alternate way to solve this problem:
If you use the Timer with a user
interface element, such as a form or
control, assign the form or control
that contains the Timer to the
SynchronizingObject property, so that
the event is marshaled to the user
interface thread.
You may find this route easier, but I haven't tried it.
Your problem, I think, is that this line:
crntreadingslbl.Text = cpuReading.ToString();
Is running outside of the UI thread. You cannot update a UI element outside of the UI thread. You need to call Invoke on the Window to call a new method on the UI thread.
All that said, why not use perfmon? It's built for purpose.
The BackGroundWorker component may help you. It is available on the toolbox so you can drag to your form.
This component exposes a set of events to execute tasks in a thread different than the UI thread. You don't have to worry about creating a thread.
All the interaction between the code running on background and the UI controls must be done via the event handlers.
For your scenario you can setup a timer to trigger the background worker at a specific interval.
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
backgroundWorker.RunWorkerAsync();
}
Then you implement the proper event handlers to actually collect data and update the UI
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Collect performance data and update the UI
}

How to know that I have another thread running apart from the main thread?

Suppose I have a routine like this:
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(Some_Work));
t.Start();
}
I need to put a condition so that, "If there is not already a thread running apart from the Main thread, start a new thread".
But how to test for whether a thread is running other than the Main thread?
There's several other threads running in your .NET app before it even gets to button1_Click. For instance, the finalizer thread is always hanging around, and I think WinForms creates one or two for itself.
Do you need to know about other threads that you've created? If so, you should keep track of them yourself. If not: why?
Edit: are you looking to kick off some background processing on demand? Have you seen the BackgroundWorker component, which manages threads for you, together with their interaction with the user interface? Or direct programming against the thread pool, using Delegate.BeginInvoke or ThreadPool.QueueUserWorkItem?
The easiest solution is of course to either store a reference to the existing thread, or just set a flag that you have a thread running.
You should also maintain that field (reference or flag) so that if the thread exits, it should unset that field so that the next "start request" starts a new one.
Easiest solution:
private volatile Thread _Thread;
...
if (_Thread == null)
{
_Thread = new Thread(new ThreadStart(Some_Work));
_Thread.Start();
}
private void Some_Work()
{
try
{
// your thread code here
}
finally
{
_Thread = null;
}
}

Is this the proper use of a mutex?

I have a situation where I might have multiple instances of a program running at once, and it's important that just one specific function not be executing in more than one of these instances at once.
Is this the proper way to use a mutex to prevent this from happening?
lock (this.GetType()) {
_log.Info("Doing Sync");
DoSync();
_log.Info("Sync Completed");
}
You said multiple instances of one application, so we're talking about two program.exe's running, right? The lock statement won't lock across multiple programs, just within the program. If you want a true Mutex, look at the System.Threading.Mutex object.
Here is a usage example:
bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
try
{
mtx.WaitOne();
MessageBox.Show("Click OK to release the mutex.");
}
finally
{
mtx.ReleaseMutex();
}
}
The createdNew variable will let you know whether or not it was created the first time. It only tells you if it has been created, though. If you want to acquire the lock, you need to call WaitOne and then call ReleaseMutex to release it. If you just want to see if you created a Mutex, just constructing it is fine.
TheSeeker is correct.
Jeff Richter's advice in Clr Via C# (p638-9) on locking is to create a private object specifically for the purpose of being locked.
private Object _lock = new Object();
// usage
lock( _lock )
{
// thread-safe code here..
}
This works because _lock cannot be locked by anything outside the current class.
EDIT: this is applicable to threads executing within a single process. #David Mohundro's answer is correct for inter-process locking.

Categories

Resources