Mutex under using block behaves differently - c#

I was following this article regarding threading here. In that under section
Mutex the following code was there.
class OneAtATimePlease
{
static void Main()
{
// Naming a Mutex makes it available computer-wide. Use a name that's
// unique to your company and application (e.g., include your URL).
using (var mutex = new Mutex (false, "oreilly.com OneAtATimeDemo"))
{
// Wait a few seconds if contended, in case another instance
// of the program is still in the process of shutting down.
if (!mutex.WaitOne (TimeSpan.FromSeconds (3), false))
{
Console.WriteLine ("Another app instance is running. Bye!");
return;
}
RunProgram();
}
}
static void RunProgram()
{
Console.WriteLine ("Running. Press Enter to exit");
Console.ReadLine();
}
}
But when I run this the code is not behaving as expected, If I run the exe (the exe generated of the above) twice it should print "Another app instance is running. Bye!". But its not going to that block.
However if i remove the using block the code behaves correctly as expected.
Please help me. I am new to threading concepts.
UPDATE
Sorry for misleading. I actually didn't do like exactly written in that article.
My code as is,
internal class Program
{
/// <summary>
/// Entry point
/// </summary>
/// <param name="args">The arguments.</param>
internal static void Main(string[] args)
{
//Misc.RunAssemblies();
var threadingDemo = new ThreadingDemo();
threadingDemo.MutexDemo();
Console.ReadLine();
}
}
namespace LearnNet.Console
{
using System.Threading;
public class ThreadingDemo
{
public void MutexDemo()
{
using (var mutex = new Mutex(false, "Global\\oreilly.com OneAtATimeDemo"))
{
// Wait a few seconds if contended, in case another instance
// of the program is still in the process of shutting down.
if (!mutex.WaitOne(0, false))
{
System.Console.WriteLine("Another app instance is running. Bye!");
return;
}
RunProgram();
}
}
static void RunProgram()
{
System.Console.WriteLine("Running. Press Enter to exit");
}
}
}
This reproduces the issue which i explained above. And if i remove the using block it behaves correctly.

You have to understand how mutex works. WaitOne acquires it and ReleaseMutex or Disposing it releases it. At the end of using block (when control flow leaves it), mutex is Disposed (that's why using block exists in the first place), and so is released. In your updated code, mutex is acquired and then immediatly released after RunProgram statement, and any subsequent instances also acquire and release it immediatly.
When you don't use using block, you don't Dispose mutex and so don't release the mutex. When Console.ReadLine statement executes - process still holds mutex. When your process ends, mutex is still released, but it's not very good practice - better always release mutex explicitly.
As for why it works in the first code you posted (before update) - there Console.ReadLine() statement is inside using block, and so when control flow blocks on this statement - process still holds the mutex.

Related

Application Shutdown

I have a project that I prepared with C#.
When the program runs, it checks for the first update.
If yes, “Update?” he asks.
If the user approves, it downloads the different update program in the background and closes the running program,
switches to the update program and starts the update.
However, sometimes the program hangs in the background for a while after it closes.
The error occurs because it cannot delete files.
How can I close the hung program or how can I delete related files?
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Equals("ExampleApp"))
{
clsProcess.Kill();
}
}
Directory.Delete(#"C:\ExampleAppFiles", true); //Problem blok
This should be checked by using Mutexes. Your first application should create a mutex and destroy it when shutdown. The installer should check for this mutex somehow like this:
static void Main()
{
using(Mutex mutex = new Mutex(false, #"Global\myMutexName"))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
}
}

How can I break into Python code called from Python.NET on a separate thread?

I would like to use PyCharm's debugger to stop at a breakpoint set in a Python method which is called from C# via Python.NET. However, the breakpoint is never hit, even though the code clearly gets executed.
The issue seems to be that the thread on which the Python method is called was created in C#. I am aware that for a thread to be visible to the debugger, settrace must be called. I thought, calling it once per thread should do the trick, but it does not. Because after calling settrace at the first execution of a Python method, my breakpoints in that method and any methods called by it, are hit. But after control passed from that method back to C#, another call of a Python method on the same thread does not hit the breakpoint.
Here is the Python side of things; imagine breakpoints set at the two print statements.
import sys
import thread
import threading
sys.path.append(r'C:\Program Files (x86)\JetBrains\PyCharm Community Edition 2018.2.4\helpers\pydev')
import pydevd
import clr
from System.Threading import Thread
from System import Action
sys.path.append(r'C:\Code\PythonNetLib\bin\Debug')
clr.AddReference('MyLib')
from MyLib import MyThread, MyThreadBase
def init_debugging():
pydevd.settrace(suspend=False)
# breakpoint here is hit
print 'debugging initialized in thread {0}, managed thread ID {1}'.format(thread.get_ident(), Thread.CurrentThread.ManagedThreadId)
def hello():
# pydevd.settrace(suspend=False)
# breakpoint here is not hit unless pydevd.settrace is called again
print 'Hello from thread {0}, managed thread ID {1}'.format(thread.get_ident(), Thread.CurrentThread.ManagedThreadId))
t = MyThread()
t.ExecuteAsync(Action(init_debugging))
t.ExecuteAsync(Action(hello))
t.ExecuteAsync(Action(t.Stop))
t.Join()
For illustration purposes here is a simplified version of the C# library referenced above containing the MyThread class:
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace MyLib
{
public class MyThread: MyThreadBase
{
private Thread _thread;
public MyThread()
{
_thread = new Thread(Execute);
_thread.Start();
}
public void Join()
{
_thread.Join();
}
}
public class MyThreadBase
{
private ConcurrentQueue<Action> _queue;
private bool _stopped;
public MyThreadBase()
{
_queue = new ConcurrentQueue<Action>();
}
public void Execute()
{
while (!_stopped)
{
if (_queue.TryDequeue(out Action action))
{
action();
}
else
{
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
}
public void ExecuteAsync(Action action)
{
_queue.Enqueue(action);
}
public void Stop()
{
_stopped = true;
}
}
}
Workaround: I noticed that my breakpoints are hit as expected when I don't create the thread in C# but use a Python thread instead like so:
t = MyThreadBase()
tPy = threading.Thread(target=lambda: t.Execute())
tPy.start()
t.ExecuteAsync(Action(init_debugging))
t.ExecuteAsync(Action(hello))
t.ExecuteAsync(Action(t.Stop))
tPy.join()
This is an option in some cases, but I do not control all thread creations in the C# libraries I want to use.
Question: What would I have to do make C# threads known to the Python debugger permanently such that the debugger doesn't lose sight of the thread after control passes back to C#. Repeatedly calling settrace seems a bit much, particularly since I can't know definitively which methods might all get called from C#.
I am using Python 2.7 and .NET Framework 4.6.1 in case that makes a difference.

C# Mutex always stuck on WaitOne

I have one process that creates the mutex and immediately takes ownership, and then when a button is clicked, it releases it:
Mutex req_mutex = new Mutex(true, "req_mutex");
...
req_mutex.WaitOne(); // not required for first click
req_mutex.ReleaseMutex();
The other process is looping and checking if the mutex exists, when it does it waits for it to be released:
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex", MutexRights.Synchronize);
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Thread.Sleep(1000);
}
}
...
req_mutex.WaitOne(); // wait for new request *********** problem here *********
req_mem.readFile(); // read request
req_mutex.ReleaseMutex(); // release req mutex for more requests
the problem is that the WaitOne doesn't continue even after the mutex was supposed to be released by the button in the first process.
Does anyone have an idea why that may be?
I think if you create the mutex with true (new Mutex(true, "req_mutex");)
you so should not need to call WaitOne() in that process.
The documentation says it is better to specify false for initiallyOwned when calling this constructor overload. https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx
EDIT: ahh, you beat me to it :) ...
You are basically acquiring the mutex twice in your first application. You can see this by killing your first application while the second one is running, and you'll get an AbandonedMutexException (which means the Mutex gets acquired). Reproduced with the following, readline instead of button clicks:
namespace Mutex_1
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = new Mutex(true, "req_mutex");
String t = string.Empty;
while (!t.Contains("q"))
{
Console.WriteLine("input: ");
t = Console.ReadLine();
Console.WriteLine("waiting for req_mutex");
req_mutex.WaitOne(); // not required for first click
Console.WriteLine("releasing req_mutex");
req_mutex.ReleaseMutex();
}
Console.ReadLine();
}
}
}
namespace Mutex_2
{
class Program
{
static void Main(string[] args)
{
Mutex req_mutex = null;
bool waitingForReqMutexCreation = true;
while (waitingForReqMutexCreation)
{
try
{
req_mutex = Mutex.OpenExisting("req_mutex");
waitingForReqMutexCreation = false;
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("req_mutex does not exist.");
Thread.Sleep(1000);
}
}
Console.WriteLine("req_mutex found");
req_mutex.WaitOne(); // wait for new request *********** problem here *********
Console.WriteLine("after req_mutex.WaitOne()");
req_mutex.ReleaseMutex(); // release req mutex for more requests
Console.ReadLine();
}
}
}
More evidence for this statement: calling ReleaseMutex twice in the parent will make things work on the first "click" (and crash the second time). You can fix this without throwing an exception by not acquiring the lock when it is created:
Mutex req_mutex = new Mutex(false, "req_mutex");
I think I found the answer to my own question...
Apparently the amount of WaitOne operations you do does matter.
I took ownership (true argument in the constructor) and did an additional WaitOne in the same thread assuming that it won't hurt.
Now in order to release the mutex I apparently had to call ReleaseMutex twice.
I guess I could still do it like this and call ReleaseMutex in a loop until an exception is thrown...

SQL CLR make sure finally block is executed

I have a SQL server CLR stored proc that is used to retrieve a large set of rows, then do a process and update a count in another table.
Here's the flow:
select -> process -> update count -> mark the selected rows as processed
The nature of the process is that it should not count the same set of data twice. And the SP is called with a GUID as an argument.
So I'm keeping a list of GUIDs (in a static list in the SP) that are currently in process and halt the execution for subsequent calls to the SP with the same argument until one currently in process finishes.
I have the code to remove the GUID when a process finishes in a finally block but it's not working everytime. There are instances (like when the user cancels the execution of the SP)where the SP exits without calling the finally block and without removing the GUID from the list so subsequent calls keeps waiting indefinitely.
Can you guys give me a solution to make sure that my finally block will be called no matter what or any other solution to make sure only one ID is in process at any given time.
Here's a sample of the code with the processing bits removed
[Microsoft.SqlServer.Server.SqlProcedure]
public static void TransformSurvey(Guid PublicationId)
{
AutoResetEvent autoEvent = null;
bool existing = false;
//check if the process is already running for the given Id
//concurrency handler holds a dictionary of publicationIds and AutoresetEvents
lock (ConcurrencyHandler.PublicationIds)
{
existing = ConcurrencyHandler.PublicationIds.TryGetValue(PublicationId, out autoEvent);
if (!existing)
{
//there's no process in progress. so OK to start
autoEvent = new AutoResetEvent(false);
ConcurrencyHandler.PublicationIds.Add(PublicationId, autoEvent);
}
}
if (existing)
{
//wait on the shared object
autoEvent.WaitOne();
lock (ConcurrencyHandler.PublicationIds)
{
ConcurrencyHandler.PublicationIds.Add(PublicationId, autoEvent); //add this again as the exiting thread has removed this from the list
}
}
try
{
// ... do the processing here..........
}
catch (Exception ex)
{
//exception handling
}
finally
{
//remove the pubid
lock (ConcurrencyHandler.PublicationIds)
{
ConcurrencyHandler.PublicationIds.Remove(PublicationId);
autoEvent.Set();
}
}
}
Wrapping the code at a higher level is a good solution, another option could be the using statement with IDisposable.
public class SQLCLRProcedure : IDisposable
{
public bool Execute(Guid guid)
{
// Do work
}
public void Dispose()
{
// Remove GUID
// Close Connection
}
}
using (SQLCLRProcedure procedure = new SQLCLRProcedure())
{
procedure.Execute(guid);
}
This isn't verified in a compiler but it's commonly referred to as the IDisposable Pattern.
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

Prevent multiple instances of a given app in .NET?

In .NET, what's the best way to prevent multiple instances of an app from running at the same time? And if there's no "best" technique, what are some of the caveats to consider with each solution?
Use Mutex. One of the examples above using GetProcessByName has many caveats. Here is a good article on the subject:
http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn);
return;
}
Here is the code you need to ensure that only one instance is running. This is the method of using a named mutex.
public class Program
{
static System.Threading.Mutex singleton = new Mutex(true, "My App Name");
static void Main(string[] args)
{
if (!singleton.WaitOne(TimeSpan.Zero, true))
{
//there is already another instance running!
Application.Exit();
}
}
}
Hanselman has a post on using the WinFormsApplicationBase class from the Microsoft.VisualBasic assembly to do this.
1 - Create a reference in program.cs ->
using System.Diagnostics;
2 - Put into void Main() as the first line of code ->
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1)
return;
That's it.
After trying multiple solutions i the question. I ended up using the example for WPF here: http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/
public partial class App : Application
{
private static Mutex _mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
const string appName = "MyAppName";
bool createdNew;
_mutex = new Mutex(true, appName, out createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
}
}
In App.xaml:
x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
It sounds like there are 3 fundamental techniques that have been suggested so far.
Derive from the Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase class and set the IsSingleInstance property to true. (I believe a caveat here is that this won't work with WPF applications, will it?)
Use a named mutex and check if it's already been created.
Get a list of running processes and compare the names of the processes. (This has the caveat of requiring your process name to be unique relative to any other processes running on a given user's machine.)
Any caveats I've missed?
i tried all the solutions here and nothing worked in my C# .net 4.0 project. Hoping to help someone here the solution that worked for me:
As main class variables:
private static string appGuid = "WRITE AN UNIQUE GUID HERE";
private static Mutex mutex;
When you need to check if app is already running:
bool mutexCreated;
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated);
if (mutexCreated)
mutex.ReleaseMutex();
if (!mutexCreated)
{
//App is already running, close this!
Environment.Exit(0); //i used this because its a console app
}
I needed to close other istances only with some conditions, this worked well for my purpose
Using Visual Studio 2005 or 2008 when you create a project for an executable, on the properties windows inside the "Application" panel there is a check box named “Make single instance application” that you can activate to convert the application on a single instance application.
Here is a capture of the window I'm talking of:
This is a Visual Studio 2008 windows application project.
http://en.csharp-online.net/Application_Architecture_in_Windows_Forms_2.0—Single-Instance_Detection_and_Management
This is the code for VB.Net
Private Shared Sub Main()
Using mutex As New Mutex(False, appGuid)
If Not mutex.WaitOne(0, False) Then
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Application.Run(New Form1())
End Using
End Sub
This is the code for C#
private static void Main()
{
using (Mutex mutex = new Mutex(false, appGuid)) {
if (!mutex.WaitOne(0, false)) {
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new Form1());
}
}
Use VB.NET!
No: really ;)
using Microsoft.VisualBasic.ApplicationServices;
The WindowsFormsApplicationBase from VB.Net provides you with a "SingleInstace" Property, which determines other Instances and let only one Instance run.
[STAThread]
static void Main() // args are OK here, of course
{
bool ok;
m = new System.Threading.Mutex(true, "YourNameHere", out ok);
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
GC.KeepAlive(m); // important!
}
From: Ensuring a single instance of .NET Application
and: Single Instance Application Mutex
Same answer as #Smink and #Imjustpondering with a twist:
Jon Skeet's FAQ on C# to find out why GC.KeepAlive matters
This article simply explains how you can create a windows application with control on the number of its instances or run only single instance. This is very typical need of a business application. There are already lots of other possible solutions to control this.
https://web.archive.org/web/20090205153420/http://www.openwinforms.com/single_instance_application.html
http://www.codeproject.com/KB/cs/SingleInstancingWithIpc.aspx
You have to use System.Diagnostics.Process.
Check out: http://www.devx.com/tips/Tip/20044
(Note: this is a fun-solution! It works but uses bad GDI+ design to achieve this.)
Put an image in with your app and load it on startup. Hold it until the app exits. The user wont be able to start a 2nd instance. (Of course the mutex solution is much cleaner)
private static Bitmap randomName = new Bitmap("my_image.jpg");
Simply using a StreamWriter, how about this?
System.IO.File.StreamWriter OpenFlag = null; //globally
and
try
{
OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning");
}
catch (System.IO.IOException) //file in use
{
Environment.Exit(0);
}
Normally it's done with a named Mutex (use new Mutex( "your app name", true ) and check the return value), but there's also some support classes in Microsoft.VisualBasic.dll that can do it for you.
This worked for me in pure C#. the try/catch is when possibly a process in the list exits during your loop.
using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
int procCount = 0;
foreach (Process pp in Process.GetProcesses())
{
try
{
if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
{
procCount++;
if(procCount > 1) {
Application.Exit();
return;
}
}
}
catch { }
}
Application.Run(new Form1());
}
Be sure to consider security when restricting an application to a single instance:
Full article:
https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813
We are using a named mutex with a fixed name in order to detect
whether another copy of the program is running. But that also means an
attacker can create the mutex first, thereby preventing our program
from running at all! How can I prevent this type of denial of service
attack?
...
If the attacker is running in the same security context as your
program is (or would be) running in, then there is nothing you can do.
Whatever "secret handshake" you come up with to determine whether
another copy of your program is running, the attacker can mimic it.
Since it is running in the correct security context, it can do
anything that the "real" program can do.
...
Clearly you can't protect yourself from an attacker running at the
same security privilege, but you can still protect yourself against
unprivileged attackers running at other security privileges.
Try setting a DACL on your mutex, here's the .NET way:
https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx
None of this answers worked for me because I needed this to work under Linux using monodevelop. This works great for me:
Call this method passing it a unique ID
public static void PreventMultipleInstance(string applicationId)
{
// Under Windows this is:
// C:\Users\SomeUser\AppData\Local\Temp\
// Linux this is:
// /tmp/
var temporaryDirectory = Path.GetTempPath();
// Application ID (Make sure this guid is different accross your different applications!
var applicationGuid = applicationId + ".process-lock";
// file that will serve as our lock
var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
try
{
// Prevents other processes from reading from or writing to this file
var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_InstanceLock.Lock(0, 0);
MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
// todo investigate why we need a reference to file stream. Without this GC releases the lock!
System.Timers.Timer t = new System.Timers.Timer()
{
Interval = 500000,
Enabled = true,
};
t.Elapsed += (a, b) =>
{
try
{
_InstanceLock.Lock(0, 0);
}
catch
{
MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
}
};
t.Start();
}
catch
{
// Terminate application because another instance with this ID is running
Environment.Exit(102534);
}
}

Categories

Resources