Start the same program many times but only one should work - c#

Is it somehow possible that if I start my program like 10 times fast in a row, but only one at a time should do something. The other keep waiting that the working program is finished or stopped.
So in the end, if I open my program 10 times, all 10 programs should be working in a row, not simultaneously.
Is this possible in c#?

You can use a named EventWaitHandle to do this, for example:
using System;
using System.Threading;
namespace Demo
{
static class Program
{
static void Main()
{
using (var waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "MyHandleName"))
{
Console.WriteLine("Waiting for handle");
waitHandle.WaitOne();
try
{
// Body of program goes here.
Console.WriteLine("Waited for handle; press RETURN to exit program.");
Console.ReadLine();
}
finally
{
waitHandle.Set();
}
Console.WriteLine("Exiting program");
}
}
}
}
Try running a few instances of this console app and watch the output.

You can use system wide Mutex or system wide Semaphore. If you create Mutex or Semaphore with name it become visible for whole system - in other words it can be visible from other processes.
Mutex syncMutex = new Mutex(false, "NAME OF MUTEX");
try
{
if(!syncMutex.WaitOne(MUTEX_TIMEOUT))
{
//fail to get mutex
return;
}
//mutex obtained do something....
}
catch(Exception ex)
{
//handle error
}
finally
{
//release mutex
syncMutex.ReleaseMutex();
}

Related

Mutex does not stop two instances of program from running at once

I am trying to use a Mutex to only allow one instance of my program to be run at a time. I reused the Mutex code from another program I was writing, only to find out that it did not stop two instances of my program from being run at once. However, my Mutex code worked in my other program. Below is the entire code of Program.cs (the code for opening files is unrelated). May you please explain how I should properly use the Mutex to prevent multiple instances of my program from being run at once? Thanks!
Note: my original code was based on this SO answer: https://stackoverflow.com/a/819808/12946280
using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace NTCSAttendanceKiosk
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Make a mutex and detect if another instance of the program is running
Mutex mutex = new Mutex(true, "AtteNTCSKioskMutex", out bool mutexResult);
if (!mutexResult)
{
// Exit if it's already running
return;
}
// Prevent the mutex from being released by the GC
GC.KeepAlive(mutex);
// Read the connection string from the file
try
{
SqlConnectionInfo.ConnectionString = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\kiosk_config\\connection_string.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file connection_string.txt does not exist. Please place the connection string in that file and place it in <your user folder>\\kiosk_config\\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading connection_string.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Read the kiosk location name from the file
try
{
SqlConnectionInfo.KioskLocation = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\kiosk_config\\location.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file location.txt does not exist. Please place the kiosk location name in that file and place it in <your user folder>\\kiosk_config\\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading location.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new KioskForm());
}
}
}
You can test the below code by running several instances simultaneously.
static void Main(string[] args)
{
using (var mutex = new Mutex(true, "UniqueSystemWideMutexName"))
{
//Timeout is set to zero so we don't block
if (!mutex.WaitOne(0))
{
Console.WriteLine("Program already running");
Console.ReadKey();
return;
}
Console.WriteLine("This is the only program running");
Console.ReadKey();
}
}
If you can't use Dispose for whatever reason, which the using block does for us, be sure to call ReleaseMutex.
You can also use OpenExisting to check if the mutex has already been created, but it's not necessary for this simple use case.

Close executor app by executed app

I have got a problem with my C# project. I got there 2 applications:
Executor application which I will call Mini Launcher
Executed application which I will call Launcher
My problem is: I want to run my Launcher by Mini launcher and in on Show event of Launcher app close Mini Launcher.
My Mini Launcher is something like splash screen but with additional functionality like upgrade Launcher, and other. Its my execution code:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = "My Directory"
startInfo.FileName = "My App";
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.();
}
}
catch
{
...
}
Have a look at the Mutex class. Named mutices provide a way for applications to send signals to one another.
The following sample shows two Console-applications. The TestMutexLauncher-application launches the TestMutex application:
using System;
using System.Diagnostics;
using System.Threading;
namespace TestMutexLauncher
{
class Program
{
static void Main(string[] args)
{
var p = Process.Start("TestMutex");
Console.WriteLine("Waiting for other process to release the mutex.");
Thread.Sleep(1000); // maybe p.WaitForInputIdle is an alternative for WinForms/WPF
Mutex mutex = null;
for (int i = 0; i < 100; i++)
{
if (Mutex.TryOpenExisting("MyUniqueMutexName", out mutex))
break;
Thread.Sleep(100);
}
if (mutex != null)
{
try
{
mutex.WaitOne();
mutex.ReleaseMutex();
}
finally
{
mutex.Dispose();
}
}
}
}
}
The launcher application starts the process and waits for a Mutex to be created in the other process. If it can acquire ownership of the the Mutex in a specified time frame, it waits to get ownership of the Mutex. After that, it realeases and disposes the Mutex.
The first task of the launched application is to create the Mutex, do the initialization actions and then release the Mutex.
using System;
using System.Threading;
namespace TestMutex
{
class Program
{
static void Main(string[] args)
{
using (var mutex = new Mutex(true, "MyUniqueMutexName"))
{
// Do something
for (int i = 0; i < 10000; i++)
Console.Write(".");
Console.WriteLine();
Console.WriteLine("Press enter...");
Console.ReadLine();
mutex.ReleaseMutex();
}
for (int i = 0; i < 10000; i++)
Console.Write(".");
Console.WriteLine();
Console.WriteLine("Press enter...");
Console.ReadLine();
}
}
}
Firstly, I would recommend you consider:
1) Do they actually need to be separate applications?
2) If so, why can't MiniLauncher just close itself after Launcher has loaded?
But if you have to do it this way, then the code you're looking for is something like this:
private void OnShow()
{
var target = Process.GetProcessesByName("MiniLauncher.exe").FirstOrDefault();
if (target != null)
{
// any other checks that this is indeed the process you're looking for
target.Close();
}
}
you can call another project executable from current running project and then you can close your application.
class Program
{
static void Main()
{
//
// Open the application "application" that is in the same directory as
// your .exe file you are running.
//
Process.Start("example.txt");
// or for another directory you need to specify full path
Process.Start("C:\\");
}
}

Only one program at a time

I have a situation where I need to have only one instance of a program running at the same time.
This would be trivial like this:
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();
}
}
Except for the small detail, that I need the EXISTING process to terminate, not the new one.
I tried making a semaphore the existing process could listen to after grabbing the above mutex, but because I want it to wait for the semaphore then I can end up in a situation where the semaphore is always signaled and thus it doesn't work.
Anyone have a good idea on how to solve this problem?
You need inter-process communication, to send a signal to the existing application. For C#, see IPC Mechanisms in C# - Usage and Best Practices.
Cine, I've written a two-Mutex logic. The first one is the "execution lock", while the second is the "monitor lock".
When the first process can't acquire the monitor lock, it will exit and release the execution lock for the new process.
I'm not sure if this is the best solution, and any feedback will be welcome.
C#:
class Program
{
private static string processName = DateTime.Now.ToString("hh.mm.ss");
private static bool exitProcess;
private static Mutex firstLock
{
get
{
return new Mutex(false, "stackoverflow.com/questions/11304052/");
}
}
private static Mutex secondLock
{
get
{
return new Mutex(false, "stackoverflow.com/questions/11304052/ #2");
}
}
static void Main(string[] args)
{
Console.WriteLine(string.Format("Process {0} starting", processName));
exitProcess = false;
while (true)
{
using (firstLock)
{
Console.WriteLine(string.Format("Process {0} trying to get #1 mutex", processName));
if (!firstLock.WaitOne(TimeSpan.FromSeconds(1), false))
{
Console.WriteLine(string.Format("Process {0} #1 mutex in use, waiting for release", processName));
bool killFirstApp = false;
while (!killFirstApp)
{
killFirstApp = LockSecondMutex();
}
continue;
}
new Thread(MonitorSecondMutex).Start();
RunProgram();
firstLock.ReleaseMutex();
break;
}
}
}
static void RunProgram()
{
while (!exitProcess)
{
Console.WriteLine(string.Format("Process {0} running", processName));
Thread.Sleep(1000);
}
}
static void MonitorSecondMutex()
{
while (true)
{
using (secondLock)
{
if (!secondLock.WaitOne(TimeSpan.FromSeconds(2), false))
{
Console.WriteLine(string.Format("Process {0} lost second mutex. Will now exit.", processName));
exitProcess = true;
break;
}
secondLock.ReleaseMutex();
}
Thread.Sleep(500);
}
}
static bool LockSecondMutex()
{
while (true)
{
using (secondLock)
{
if (!secondLock.WaitOne(TimeSpan.FromSeconds(2), false))
{
continue;
}
Thread.Sleep(5000);
secondLock.ReleaseMutex();
}
return true;
}
}
}
You could possibly get this done by requesting access to some limited system-wide resource, such as port. Your application could bind a socket to a specific port on launch. If it fails to bind, send a termination signal to the running instance and try again.

C# Making a Thread wait for a Timer

I'm writing a C# program that runs two IRC connections at once.
The connections are threaded, and each thread starts like so:
MainThread = new Thread(new ThreadStart(StartMainProcessor));
MainThread.IsBackground = false;
MainThread.Start();
private void StartMainProcessor() {
MainProcessor.Bot.Connect();
//while (true) { }
}
Bot.Connect() looks like this (somewhat abridged version):
public void Connect() {
try {
Client.Connect(IRCHelper.SERVER, IRCHelper.PORT);
}
catch (CouldNotConnectException e) {
Reconnect(true);
return;
}
try {
Client.Listen();
}
catch (Exception e) {
Reconnect(false);
return;
}
}
This works fine until the bot disconnects (which will always happen eventually, it's the nature of IRC).
When it disconnects, Reconnect() is called, which starts a timer. When that timer expires the bot is meant to then call Connect() again. The reason for the timer is that an IRC server will refuse an immediate reconnection sometimes.
However, once the Connect() method has ended, the Thread ends, and the program (console application) exits. (Client.Listen() is blocking)
I had previously overcome this problem by adding while (true) { } in StartMainProcessor()... But this eats up 100% CPU, and I'd really prefer a different solution.
Thank you for your help. :)
Sounds like you need a signaling construct. For example, you could use something like an AutoResetEvent to block the thread calling Reconnect, i.e. call Reconnect, start the timer and then block the thread. Then set the auto reset event in the timer expired event handler to allow the thread to continue (unblock) and call Connect.
I'm not a fan of spinning the processor - wastes huge amounts of CPU resources when you add infinite loops or sleeps in loops.
Why don't you just Thread.Sleep inside Bot.Reconnect? That would keep your thread alive and wake it up when ready to call Bot.Connect again.
You might want to try something like that
private bool canExitThread;
private void StartMainProcessor()
{
while (canExitThread)
{
//do the magic here
System.Threading.Thread.Sleep(1); //make sure you allow thread to do the job, otherwise you will get 100 cpu usage
//do the connecting, disconnecting, listening
}
}
Also can you check if Client is connected? if so then you should be checking that within the main loop and if it's disconnected - call the connect method.
Hope that gives you an idea how to do it.
Also have a look the the article below, which might explain things a little bit more.
http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx
how about something like this
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting server..");
foreach (var connection in new[] {new Connection(TimeSpan.FromSeconds(1)), new Connection(TimeSpan.FromSeconds(1))})
ThreadPool.QueueUserWorkItem(connection.Connect);
Console.WriteLine("Server running. Press Enter to quit.");
Console.ReadLine();
}
}
public class Connection //might be good to implement IDisposable and disconnect on Dipose()
{
private readonly TimeSpan _reConnectionPause;
public Connection(TimeSpan reConnectionPause)
{
_reConnectionPause = reConnectionPause;
}
//You probably need a Disconnect too
public void Connect(object state)
{
try
{
//for testing assume connection success Client.Connect(IRCHelper.SERVER, IRCHelper.PORT);
Debug.WriteLine("Open Connection");
}
catch (Exception)
{
//You might want a retry limit here
Connect(state);
}
try
{
//Client.Listen();
//Simulate sesison lifetime
Thread.Sleep(1000);
throw new Exception();
}
catch (Exception)
{
Debug.WriteLine("Session end");
Thread.Sleep(_reConnectionPause);
Connect(state);
}
}
}
}
I presume you have a Main method, so why don't we start there:
private static readonly MAX_NUM_BOTS = 2;
static void Main(string[] args)
{
List<Thread> ircBotThreads = new List<Thread>();
for(int numBots = 0; numBots < MAX_NUM_BOTS; numButs++)
{
Thread t = new Thread(()=>{StartMainProcessor();});
t.IsBackground = false;
t.Start();
ircBotThreads.Add(t);
}
// Block until all of your threads are done
foreach(Thread t in ircBotThreads)
{
t.Join();
}
Console.WriteLine("Goodbye!");
}
private static void StartMainProcessor()
{
MainProcessor.Bot.Connect();
}
Then you can do something like this:
// 30 second time out (or whatever you want)
private static readonly TimeSpan TIMEOUT = TimeSpan.FromSeconds(30.0);
// specify the maximum number of connection attempts
private static readonly int MAX_RECONNECTS = 10;
public void Connect()
{
bool shouldListen = false;
// This is your connect and re-connect loop
for(int i = 0; i < MAX_RECONNECTS; i++)
{
try
{
Client.Connect(IRCHelper.SERVER, IRCHelper.PORT);
shouldListen = true;
}
catch (CouldNotConnectException e)
{
// It's OK to sleep here, because you know exactly
// how long you need to wait before you try and
// reconnect
Thread.Sleep((long)TIMEOUT.TotalMilliseconds);
shouldListen = false;
}
}
while(shouldListen)
{
try
{
Client.Listen();
}
catch (Exception e)
{
// Handle the exception
}
}
}
This is a very rough draft, but the concept is that you keep trying to reconnect until you fail. Once you connect, then you listen (I presume you listen for something in IRC) and you process the data until you decide that you no longer need to be doing that work.

Synchronisation of Two Threads

I have two threads in c#.. Now i need to wait for a particular statement to be executed before I can continue execution in the other thread which obviously is a case of synchronisation.
Is there any code that can carry this out as in using an in-built method?
This is the code example:
public void StartAccept()
{
try
{
newSock.BeginAccept(new AsyncCallback(Accepted), newSock);
}
catch (ArgumentException)
{
MessageBox.Show("Error in arguments while using begin-accept", "Error", MessageBoxButtons.OK);
}
catch (ObjectDisposedException)
{
MessageBox.Show("socket closed while using begin-accept", "Error", MessageBoxButtons.OK);
}
catch (SocketException)
{
MessageBox.Show("Error accessing socket while using begin-accept", "Error", MessageBoxButtons.OK);
}
catch (InvalidOperationException)
{
MessageBox.Show("Invalid operation while using begin-accept", "Error", MessageBoxButtons.OK);
}
catch (Exception)
{
MessageBox.Show("Exception occurred while using begin-accept", "Error", MessageBoxButtons.OK);
}
}
This receives data from the desired host which is selected by the code:
private void listBox1_Click(object sender, EventArgs e)
{
String data = (String)this.listBox1.SelectedItem;
ip = Dns.GetHostAddresses(data);
clientIP = new IPEndPoint(ip[0], 5555);
newSock.Bind(clientIP);
newSock.Listen(100);
}
So in order to start receiving data I need to initialise the socket to the particular remote host which is done when i click on one of the hosts shown in the listbox.
For this I need the synchronization.
Take a look at AutoResetEvent and ManualResetEvent. They are signals that makes synchronisation between threads possible.
The first thread that needs to wait for something to get done will do myEvent.WaitOne(), which blocks until the other thread calls myEvent.Set().
Let's say we have two threads, where one of them needs to do some kind of initialisation before the other thread can continue. You then share a AutoResetEvent between the two, let's call it myEvent.
// Signal example
using System;
using System.Threading;
class MySync
{
private readonly AutoResetEvent _myEvent;
public MySync(AutoResetEvent myEvent)
{
_myEvent = myEvent;
}
public void ThreadMain(object state)
{
Console.WriteLine("Starting thread MySync");
_myEvent.WaitOne();
Console.WriteLine("Finishing thread MySync");
}
}
class Program
{
static void Main(string[] args)
{
AutoResetEvent myEvent = new AutoResetEvent(false);
MySync mySync = new MySync(myEvent);
ThreadPool.QueueUserWorkItem(mySync.ThreadMain);
Console.WriteLine("Press enter to continue...");
Console.ReadLine();
myEvent.Set();
Console.WriteLine("Press enter to continue...");
Console.ReadLine();
Console.WriteLine("Finishing");
}
}
Don't confuse this with a shared resource where the access order doesn't matter. For example, if you have a shared list or a shared dictionary you need to wrap it in a mutex in order to guarantee that they execute correctly.
// Mutex example
object mySync = new object();
Dictionary<int, int> myDict = new Dictionary<int, int>();
void threadMainA()
{
lock(mySync)
{
mySync[foo] = bar;
}
}
void threadMainB()
{
lock(mySync)
{
mySync[bar] = foo;
}
}
You can use an AutoResetEvent.
In the following example two methods get called by different threads and DoSomethingA() will be executed and finish before DoSomethingB() starts:
AutoResetEvent resetEvent = new AutoResetEvent(false);
void ThreadWorkerA()
{
// perform some work
DoSomethingA();
// signal the other thread
resetEvent.Set();
}
void ThreadWorkerB()
{
// wait for the signal
resetEvent.WaitOne();
// perform the new work
DoSomethingB();
}
Note: remember to dispose the AutoResetEvent :)
Java has something called Join. I suspect there will be a predefined method in C# too.

Categories

Resources