I'm testing some threading code, and using LinqPad I noticed that I'm able to acquire the same named Mutex from two different LinqPad tabs. After diagnosing for I while I realized that it only happens in LinqPad and not in regular code.
Any help why it happens? AFAIK LinqPad uses different App Domains to execute each tab but I'm not sure how that should change anything since I'm using a named mutex.
Here's the code:
var mutexName = #"Global\TestMutex".Dump();
var createdNew = false;
var mtx = new Mutex(true, mutexName, out createdNew);
(createdNew ? "I own the mutex" : "I don't own the mutex").Dump();
mtx.WaitOne(); // Not really necessary
"I aquired the mutex".Dump();
string.Format("PID: {0} ThreadID: {1} AppDomainID: {2}",
Process.GetCurrentProcess().Id,
AppDomain.GetCurrentThreadId(),
AppDomain.CurrentDomain.Id).Dump();
Util.ReadLine();
Paste this code into two LinqPad tabs and it will consistently reproduce the issue, sometimes you'd have to stop and start the second tab though.
Your Mutex is being collected by the GC, so that the first program closes it before the second one starts.
Add GC.KeepAlive(mtx) after the ReadLine to force the Mutex to survive until then.
Related
I am trying to use the SpeakAsync() method to speak some text. However, it doesn't start speaking anything until I call Speak(). I don't want to call Speak(). If I remove the Speak() method from this code nothing gets called at all:
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
synth.SelectVoice("ScanSoft Emily_Dri20_22kHz");
synth.Rate = 10;
synth.Volume = 100;
synth.SpeakAsync("oh, i'm a lumberjack and i'm okay! I sleep all night and I work all day!");
synth.SpeakAsync("If he was dying he wouldn't bother writing ah! He'd just say it!");
synth.Speak("i don't want to go on the cart.");
synth.SpeakAsync("We don't have a lord. We're an anarcho-syndicalist commune.");
synth.SpeakAsync("If you do not show us the grail, we shall take your castle by force!");
synth.Speak("what do you mean, an african swallow or a european swallow?");
UPDATE:
It appears other people are having this problem but no solution has been found yet:
other people having this problem
It's because Speak is a blocking call which keeps the program running. Since you're running this as a console application add Console.ReadKey(); at the end of your code to ensure that the application remains running until the user presses a key.
Otherwise, the main thread will exit because SpeakAsync returns immediately so your program is flying through all those lines and then exiting which is why you don't hear anything.
Update based on comments -
The using block is disposing the SpeechSynthesizer almost immediately which is why nothing can be heard. You can either place Console.ReadKey(); just before the closing brace of the using block or remove the using block and dispose of it manually later on.
I have the same BackgroundWorker code piece in two simultaneously running applications. Will this code avoid the problem of same resource getting access by two processes and run smoothly?
void bw_DoWork(object sender, DoWorkEventArgs e)
{
bool flag = false;
System.Threading.Thread.Sleep(1000);
while (flag.Equals(false))
{
string dir = #"C:\ProgramData\Msgs";
try
{
if (Directory.GetFiles(smsdir).Length > 0)
{
flag = true;
}
}
catch (Exception exc)
{
Logger.Log("Dir Access Exception: " + exc.Message);
System.Threading.Thread.Sleep(10);
}
}
On one level, depending on what you're doing, there's nothing wrong with having multiple applications accessing the same directory or file. If it's just read access, then by all means, both can access it at once.
If you've got identical code in multiple applications, then a Boolean isn't going to cut it for synchronization, no matter what you do: Each application has its own copy of the Boolean, and cannot modify the other.
For cross application synhronization, I'd use the Mutex class. There's a constructor that takes a string parameter, specifying the name of the Mutex. Mutex names are unique across all of Windows, not just your application. You can do Mutex m = new Mutex(false, "MySpecialMutex"); in two different applications, and each object will be referring to the same thing.
No, it won't solve the issue because setting the boolean's value and checking it is not an atomic function and is thus not thread safe. You have to use either a Mutex or a Monitor object.
Check this link for more info: Monitor vs Mutex in c#
No, it will not -- at least, the code you have pasted will not accomplish any sort of meaningful process synchronization.
If you want a more detailed and helpful answer, you are going to need to be more specific about what you are doing.
You must come up with some kind of cross-process synchronization scheme - any locking mechanism you use in that code is irrelevant if you're trying to prevent collisions between two processes as opposed to two threads running on the same process.
A good way to do locking across processes like this is to use a file. First process in creates a file and opens it with exclusive access, and then deletes it when its done. The second process in will either see that the file exists and have to wait till it doesn't or it will fail when attempting to open the file exclusively.
no, 'flag' is local to the scope of the method, which is local to the scope of the thread. In other words, it will also equal false.
This is what the lock function is for. Use it like this
In your class, declare a private object called gothread.
in your method write it like this
lock(gothread)
{
// put your code in here, one thread will not be able to enter when another thread is already
// in here
}
Isn't there a better looking statement (or way) to keep the console from disappearing than the hackish Console.ReadLine() call. Something that's more expressive of the purpose of, more orthogonal to, keeping the Console visible ?
If you are still developing application you can run via Ctrl + F5 (Without debugging)
otherwise you can use Console.ReadKey() (same but there is no more option)
You can do:
Console.ReadKey();
Console.ReadLine() is not really hackish, your pausing the screen to wait for input. The input can either be a single key, or a string.
Update
One nice thing about the ReadKey() method is that it "waits, that is, blocks on the thread issuing the ReadKey method, until a character or function key is pressed." MSDN
This is different than ReadLine which takes in a string. Arguably, cleaner.
It depends on the context. If you're talking about running a command line, debugging through your code, and then being able to view the results on the console you have two options:
If you run with the debugger attached (f5), you must use Console.ReadLine
If you run without the debugger attached (ctrl + f5), it will stay open ... but then you obviously can't debug through.
I'm not sure why that's the default behavior, but there it is :-)
I usually use one of these:
Console.ReadKey(true); //You might want to put this in an infinite loop
new AutoResetEvent(false).WaitOne();
In VS You can also run (Ctrl + F5) the program (in distinction to running in debug) and it will add a system pause after it finishes executing.
I'd say that WaitOne, and just running (& not debugging) the program are your non-hackish options.
If you do want to debug, perhaps set a breakpoint at the last }.
Depends on what I am doing. If I am doing multi-threaded work and want my Console application to remain alive until all other work is done, I usually do something like this. (Similar to MasterMastic)
using System;
using System.Threading;
namespace Test_Console
{
class Program
{
static EventWaitHandle EWHandle;
static void Main(string[] args)
{
EWHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
Thread WorkThread = new Thread(new ThreadStart(DoStuff));
EWHandle.WaitOne();
}
static void DoStuff()
{
Console.WriteLine("Do what you want here");
EWHandle.Set();
}
}
}
Of course, there's always just using the regular breakpoints and the other debugging tools if that's what you're going for.
How can I create a system/multiprocess Mutex to co-ordinate multiple processes using the same unmanaged resource.
Background:
I've written a procedure that uses a File printer, which can only be used by one process at a time. If I wanted to use it on multiple programs running on the computer, I'd need a way to synchronize this across the system.
You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
That doesn't answer the question:
How can I create a system/multiprocess Mutex
To create a system-wide mutex, call the System.Threading.Mutex constructor that takes a string as an argument. This is also known as a 'named' mutex. To see if it exists, I can't seem to find a more graceful method than try catch:
System.Threading.Mutex _mutey = null;
try
{
_mutey = System.Threading.Mutex.OpenExisting("mutex_name");
//we got Mutey and can try to obtain a lock by waitone
_mutey.WaitOne();
}
catch
{
//the specified mutex doesn't exist, we should create it
_mutey = new System.Threading.Mutex("mutex_name"); //these names need to match.
}
Now, to be a good programmer, you need to, when you end the program, release this mutex
_mutey.ReleaseMutex();
or, you can leave it in which case it will be called 'abandoned' when your thread exits, and will allow another process to create it.
[EDIT]
As a side note to the last sentence describing the mutex that is abandoned, when another thread acquires the mutex, the exception System.Threading.AbandonedMutexException will be thrown telling him it was found in the abandoned state.
[EDIT TWO]
I'm not sure why I answered the question that way years ago; there is (and was) a constructor overload that is much better at checking for an existing mutex. In fact, the code I gave seems to have a race condition! (And shame on you all for not correcting me! :-P )
Here's the race condition: Imagine two processes, they both try to open the existing mutex at the same time, and both get to the catch section of code. Then, one of the processes creates the mutex and lives happily ever after. The other process, however, tries to create the mutex, but this time it's already created! This checking/creating of a mutex needs to be atomic.
http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx
So...
var requestInitialOwnership = false;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
I think the trick here is that it appears that you have an option that you don't actually have (looks like a design flaw to me). You sometimes can't tell if you own the mutex if you send true for requestInitialOwnership. If you pass true and it appears that your call created the mutex, then obviously you own it (confirmed by documentation). If you pass true and your call did not create the mutex, all you know is that the mutex was already created, you don't know if some other process or thread which perhaps created the mutex currently owns the mutex. So, you have to WaitOne to make sure you have it. But then, how many Releases do you do? If some other process owned the mutex when you got it, then only your explicit call to WaitOne needs to be Released. If your call to the constructor caused you to own the mutex, and you called WaitOne explicitly, you'll need two Releases.
I'll put these words into code:
var requestInitialOwnership = true; /*This appears to be a mistake.*/
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
if ( !mutexWasCreated )
{
bool calledWaitOne = false;
if ( ! iOwnMutex(m) ) /*I don't know of a method like this*/
{
calledWaitOne = true;
m.WaitOne();
}
doWorkWhileHoldingMutex();
m.Release();
if ( calledWaitOne )
{
m.Release();
}
}
Since I don't see a way to test whether you currently own the mutex, I will strongly recommend that you pass false to the constructor so that you know that you don't own the mutex, and you know how many times to call Release.
You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
I have not had good luck using the System Mutex described above using Mono under Linux. I'm probably just doing something simple wrong but the following works well and cleans up nicely if the process exits unexpectedly (kill -9 ). Would would be interested to hear comments or critisisms.
class SocketMutex{
private Socket _sock;
private IPEndPoint _ep;
public SocketMutex(){
_ep = new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 7177);
_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_sock.ExclusiveAddressUse = true; // most critical if you want this to be a system wide mutex
}
public bool GetLock(){
try{
_sock.Bind(_ep); // 'SocketException: Address already in use'
}catch(SocketException se){
Console.Error.WriteLine ("SocketMutex Exception: " se.Message);
return false;
}
return true;
}
}
I have a console application in C# in which I run various arcane automation tasks. I am well aware that this should really be a Windows Service since it needs to run continuously, but I don't want to do that at this time. (So, don't suggest that as an answer).
In the meantime, I need some sample C# code that will allow me to determine if there's already an instance of the Application running.
In the old VB6.0 days, I would have used App.PrevInstance()
I want to be able to do this in my Main method:
static void Main()
{
if(!MyApp.IsAlreadyRunning())
{
while(true)
{
RockAndRollAllNightAndPartyEveryDay();
}
}
}
The proper way to use a mutex for this purpose:
private static Mutex mutex;
static void Main()
{
// STEP 1: Create and/or check mutex existence in a race-free way
bool created;
mutex = new Mutex(false, "YourAppName-{add-your-random-chars}", out created);
if (!created)
{
MessageBox.Show("Another instance of this application is already running");
return;
}
// STEP 2: Run whatever the app needs to do
Application.Run(new Form1());
// No need to release the mutex because it was never acquired
}
The above won't work for detecting if several users on the same machine are running the app under different user accounts. A similar case is where a process can run both under the service host and standalone. To make these work, create the mutex as follows:
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var mutexsecurity = new MutexSecurity();
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.ChangePermissions, AccessControlType.Deny));
mutexsecurity.AddAccessRule(new MutexAccessRule(sid, MutexRights.Delete, AccessControlType.Deny));
_mutex = new Mutex(false, "Global\\YourAppName-{add-your-random-chars}", out created, mutexsecurity);
Two differences here - firstly, the mutex needs to be created with security rights that allow other user accounts to open/acquire it. Second, the name must be prefixed with "Global" in the case of services running under the service host (not sure about other users running locally on the same machine).
Jeroen already answered this, but the best way by far is to use a Mutex... not by Process. Here's a fuller answer with code.
I've updated this answer after seeing some comments about a race condition to address that by instead using the Mutex Constructor
Boolean createdNew;
Mutex mutex;
try
{
mutex = new Mutex(false, "SINGLEINSTANCE" out createdNew);
if (createdNew == false)
{
Console.WriteLine("Error : Only 1 instance of this application can run at a time");
Application.Exit();
}
// Run your application
}
catch (Exception e)
{
// Unable to open the mutex for various reasons
}
finally
{
// If this instance created the mutex, ensure that
// it's cleaned up, otherwise we can't restart the
// application
if (mutex && createdNew)
{
mutex.ReleaseMutex();
mutex.Dispose();
}
}
Notice the try{} finally{} block. If you're application crashes or exits cleanly but you don't release the Mutex then you may not be able to restart it again later.
The most simple (and reliable) way to do this, is using a Mutex. Use the WaitOne method of the Mutex class to wait until the mutex becomes available. An added advantage, this will not require any infinite loops
You can search process names of existing system process. For example code, see this blog post.
You can also used a named system Mutex to see if your process is already running.
Here is some sample code. This tends to be more reliable in my experience, and is much simpler, more understandable code.
This article talks about it: Prevent a second process instance from running. It's in VB.net but you can convert it.
The problem in writing a generic function that checks whether the current application is already running comes from the fact that the ProcessName property of the Process object seems to be limited to 15 characters, so longer process names are truncated.
A safer way to retrieve a process name is to get the filename of its main module and dropping the extension. The following reusable routine uses this approach:
Function AppIsAlreadyRunning() As Boolean
' get the filename of the main module
Dim moduleName As String = Process.GetCurrentProcess.MainModule.ModuleName
' discard the extension to get the process name
Dim procName As String = System.IO.Path.GetFileNameWithoutExtension(moduleName)
' return true if there are 2 or more processes with that name
If Process.GetProcessesByName(procName).Length > 1 Then
Return True
End If
End Function
// Allow running single instance
string processName = Process.GetCurrentProcess().ProcessName;
Process[] instances = Process.GetProcessesByName(processName);
if (instances.Length > 1)
{
MessageBox.Show("Application already Running", "Error 1001 - Application Running");
return;
}
Gracefully exit application with messagebox as shown above if application is already running
You can use Process.GetProcessesByName("MyProcessName"); in the System.Diagnostics namespace to check if there is an instance of your process running.
EDIT: Very good observations in the comments! This is a (very) simplistic way of doing it, and certainly doesn't cover all the bases.
Using a kernal object is the only correct way to implement single instance protection in Windows.
This statement:
mutex = Mutex.OpenExisting("SINGLEINSTANCE");
won't work if someone else copies this line from Stackoverflow and runs their program before your program, since that other guy grabbed "SINGLEINSTANCE" before you did. You want to include a GUID in your mutex name:
mutex = Mutex.OpenExisting("MyApp{AD52DAF0-C3CF-4cc7-9EDD-03812F82557E}");
This technique will prevent the current user from running more than one instance of your program, but will not prevent another user from doing so.
To ensure that only one instance of your application can run on the local computer, you need to do this:
mutex = Mutex.OpenExisting("Global\MyApp{AD52DAF0-C3CF-4cc7-9EDD-03812F82557E}");
See the help for the CreateMutex api.
In one of my projects I used SingleInstance Component
Another way to do it is to bind to an address on the local machine (as a TCP listener would). Only one process at a time can bind to a port/address combination. So pick a port on the loopback adapter and have at it.
This has the nice side-effects of:
Working even if someone renames the executable
Resetting itself when the application crashes
The technique is portable across other operating systems
On the down-side, it can fail if there's another application that binds to that particular port.
As requested, some code to bind to a address/port is below. This is ripped out of something else. It is incomplete, but the necessary bits are here.
using System.Net;
using System.Net.Sockets;
[...]
// Make up a number that's currently unused by you, or any
// well-known service. i.e. 80 for http, 22 for ssh, etc..
int portNum = 2001;
// This binds to any (meaning all) adapters on this system
IPAddress ipAddress = IPAddress.Any;
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, portNum);
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// The next statement will throw an exception if anyone has done this Bind!
listener.Bind(localEndPoint);
As long as listener is not garbage collected (falls out of scope) or the program doesn't terminate: that port on that adapter is yours and only yours. If anything should happen to listener then it becomes available for someone else to use. For purposes of a lock, you should probably have listener be static somewhere.