Is it possible to get notified when a specific Windows application(s) is terminated/closed when using C# and .Net? It could be any application, that is listen in the Windows job list.
You can use the WaitForExit method like this:
var process = Process.GetProcessById(process_id);
process.WaitForExit();
This will cause the executing thread to wait until the process has exited.
If you don't want to block the thread, and instead receive a notification when the process has exited, you can use the following:
public static void NotifyOnProcessExits(Process process, Action action)
{
Task.Run(() => process.WaitForExit()).ContinueWith(t => action());
}
And use it like this:
NotifyOnProcessExits(process, () => Console.WriteLine("Process has exited"));
Please note that this solution will keep one thread-pool thread waiting for the process to exit. You might be able to find a better solution that is truly asynchronous, I am not sure though.
Yes using System.Diagnostics . I have written a program before that would kill double instances of an application. I don't think there are events you can wire up to monitor when a specific program has been closed but you can check periodically if the program still exists on the list of processes and trigger an even when it is not found.
if(!Process.GetProcesses().Any(p => p.ProccessId == Id)); { //or Process Name
//Your logic here
}
You could register the process and then get notified via an event using
ThreadPool.RegisterWaitForSingleObject
This will allow your application that is currently doing the monitoring to run as expected, without being blocked.
See here.
I'm feeling so dumb to ask this but..
How can I prevent my app from exiting without blocking the thread?
Currently it is a console application. But it will be a "windows-app"
(right click in VS on the startup project -> app -> output type: (first) windows app - not a store app. This is just to have an "invisible" app without any kind of GUI. So I can't use Console.ReadLine() later)
What I'm currently doing
var app = WebApp.Start<OwinStartup>(url);
Console.ReadLine(); // wait until I press enter
app.Dispose();
I don't want to block my thread like this
while (isRunning)
{
Thread.Sleep(1000);
}
What possibilities do I have to achieve this?
So a disclaimer, I am not familiar with WebApp at all. However, you could use a ManualResetEvent to accomplish what you want.
using (var app = WebApp.Start<OwinStartup>(url))
{
ManualResetEvent stopHandle = new ManualResetEvent(false);//Might need to be true, I always get this mixed up.
//Pass handle to app somehow
stopHandle.WaitOne();
}
So this code creates the app and then creates a ManualResetEvent. This event is then passed to the app and then the thread stops and waits for it to be set. Inside the app you can set it whenever you want, you can read console input, wait for a button on a page to be clicked or whatever.
I am assuming here that the WebApp class handles creating another thread or uses async to handle web requests. Otherwise you would need to run the app on another thread.
If I have understood your question correctly you are looking for something like below.
Dispatcher.Run();
the above piece of code will keep the thread/app active and wait for message on the Dispatcher as long as shutdown has not been requested on that particular Dispatcher.
Not for a console project you need to add reference to WindowsBase
You can then decide to shutdown the application from another thread.
private static void Main(string[] args)
{
var waitThread = new Thread(Dispatcher.Run) {IsBackground = false};
waitThread.Start();
Console.WriteLine("Application is still running");
//to exit application shutdown waitThread here
}
https://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.run(v=vs.110).aspx
A very simplistic approach will be to display a MessageBox with OK button only. This will block the execution until the user has clicked the button or simply pressed "Enter" key. This I think resembles the behavior of the "Console.ReadLine()" provided you don't actually expect any input at this stage.
You can do an asynchronous application wait using the async and await tag. And this is assuming you have .NET 4.5 as your framework.
private static bool hasExitedApp; // flag to be used for exiting
private static void Main(string[] args)
{
Console.WriteLine("Application is running...");
performAsynchronousWait();
Console.WriteLine("Application is still running...");
// do other processes here
}
private async static void performAsynchronousWait()
{
while (!hasExitedApp)
await Task.Delay(100); // Task.Delay uses a timer, so there's no blocking the UI
Console.WriteLine("Has excited the application...");
// do shutdown processes here
}
I used console here to show that the execution of main will still continue, but the method performAsynchronousWait is still executing. You're UI thread will continue but a background process will still happen.
I have a console application, in which I have a connection to a third party windows service on a remote server by tcp/ip.
The call Hierarchy likes:
static class Program
{
[MTAThread]
static void Main()
{
MyApplication.Start();
The Start method
public static void Start()
{
lock (SyncVar)
{
ThreadStart ts = new ThreadStart(MainCode);
MainCodeThread = new Thread(ts);
MainCodeThread.IsBackground = false;
MainCodeThread.Start();
The detail of main thread has:
private static void MainCode()
{
try
{
// connect to the remote server, against a windows service
TelephonyServer tServer = new TelephonyServer(sIpaddress, "username", "password");
while (true)
{
Task consumer = Task.Run(() =>
{
if (data != "")
{
ProcessEachChannel(data);
});
Task producer = Task.Run(() =>
{
// blah blah
});
In the method ProcessEachChannel, we have
public bool ProcessEachChannel(string workItem)
{
ChannelResource cr = tServer.GetChannel();
// blah blah
}
Now the application is working well. However if I click the red exit cross of the application or click stop debugging button from Visual Studio, the resources ChannelResource cr is not destroyed at all. I found the fact from the remote server service control dashboard.
I tried some code
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.Exited += new EventHandler(OnExited);
It is not helpful. I heard some tricks to manage the thread by passing parameters to the main thread then set something true or false etc but just no clue.
The program will not exit until all running threads have been stopped.
Replace the while (true) in the thread code with while (!stopThread.WaitOne(10, false)) where stopThread is a WaitHandle like ManualResetEvent.
Then, when the application shuts down, Set the event and wait for the thread to exit.
Also note that some 3rd-party frameworks depend on Dispose being called on their object because they need to manage the lifetime of some separate threads they've spawned. F.e. read VoiceElements document and see how they call Disconnect and Dispose on a ChannelResource they've got from GetChannel(). Please check with the provider when and where you need to release used resources yourself.
If you kill the process, instead of closing it gracefully (and that is what you do when you close the console window or press the stop buttpn in debugger), there's no chance for any cleanup code to run.
you have to implement some exit handler, perhaps catching a ctrl-c press and then return from your threads, so all objects can cleanly dispose themselves.
I am considering creating an asynchronous logging component having a dedicated thread that will read new items from queue and write to database, file, etc. If I create a thread as a background one - it will be terminated as soon as the process ends thus all items in queue will be lost. If I create it is a foreground one - I will have to figure out when to stop it as it will prevent the application from closing. Is there any way not to make developers remember to 'stop' logging functionality before application exits?
I believe you can:
Subscribe to the AppDomain.ProcessExit event;
Use a Volatile sentinel variable as a shutdown flag;
Set the flag when the ProcessExit event fires up;
Monitor the state of the flag inside your thread, and gracefully shut down accordingly.
This way you may keep a foreground thread aware of impending doom.
First of all I have to agree with the comments above. I would just use something like NLog rather than trying to roll my own. While it may seem like there is a lot to learn at first, it is still better than writing and debugging your own.
If you really want to travel this road, my recommendation would be to use a 'using' statement and IDisposable to control the asynchronous behavior. Just start a normal thread in the ctor and signal & Join the thread on Dispose().
Example usage:
void Main()
{
using (new Logging())
{
...
}
}
Example class (untested):
class Logging :IDisposable
{
ManualResetEvent _stop = new ManualResetEvent(false);
Thread _worker = null;
public Logging()
{
_worker = new Thread(AsyncThread);
_worker.Start();
}
public void Dispose()
{
_stop.Set();
_worker.Join();
}
public void AsyncThread()
{
...
}
}
In your logging routine, you will want to test if the thread is running and then decide between queuing the log write or directly appending to the log output. This way log messages before and after the async thread will continue to work correctly.
Writing an infinite loop is simple:
while(true){
//add whatever break condition here
}
But this will trash the CPU performance. This execution thread will take as much as possible from CPU's power.
What is the best way to lower the impact on CPU?
Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for Sleep() method may indicate an unresponsive application to the operating system.
Let's say I need to perform a task each minute or so in a console app.
I need to keep Main() running in an "infinite loop" while a timer will fire the event that will do the job. I would like to keep Main() with the lowest impact on CPU.
What methods do you suggest. Sleep() can be ok, but as I already mentioned, this might indicate an unresponsive thread to the operating system.
LATER EDIT:
I want to explain better what I am looking for:
I need a console app not Windows service. Console apps can simulate the Windows services on Windows Mobile 6.x systems with Compact Framework.
I need a way to keep the app alive as long as the Windows Mobile device is running.
We all know that the console app runs as long as its static Main() function runs, so I need a way to prevent Main() function exit.
In special situations (like: updating the app), I need to request the app to stop, so I need to infinitely loop and test for some exit condition. For example, this is why Console.ReadLine() is no use for me. There is no exit condition check.
Regarding the above, I still want Main() function as resource friendly as possible. Let asside the fingerprint of the function that checks for the exit condition.
To avoid the infinity loop simply use a WaitHandle. To let the process be exited from the outer world use a EventWaitHandle with a unique string. Below is an example.
If you start it the first time, it simple prints out a message every 10 seconds. If you start in the mean time a second instance of the program it will inform the other process to gracefully exit and exits itself also immediately. The CPU usage for this approach: 0%
private static void Main(string[] args)
{
// Create a IPC wait handle with a unique identifier.
bool createdNew;
var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "CF2D4313-33DE-489D-9721-6AFF69841DEA", out createdNew);
var signaled = false;
// If the handle was already there, inform the other process to exit itself.
// Afterwards we'll also die.
if (!createdNew)
{
Log("Inform other process to stop.");
waitHandle.Set();
Log("Informer exited.");
return;
}
// Start a another thread that does something every 10 seconds.
var timer = new Timer(OnTimerElapsed, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
// Wait if someone tells us to die or do every five seconds something else.
do
{
signaled = waitHandle.WaitOne(TimeSpan.FromSeconds(5));
// ToDo: Something else if desired.
} while (!signaled);
// The above loop with an interceptor could also be replaced by an endless waiter
//waitHandle.WaitOne();
Log("Got signal to kill myself.");
}
private static void Log(string message)
{
Console.WriteLine(DateTime.Now + ": " + message);
}
private static void OnTimerElapsed(object state)
{
Log("Timer elapsed.");
}
You can use System.Threading.Timer Class which provides ability to execute callback asynchronously in a given period of time.
public Timer(
TimerCallback callback,
Object state,
int dueTime,
int period
)
As alternative there is System.Timers.Timer class which exposes Elapsed Event which raises when a given period of time is elapsed.
Why would you condone the use of an infinite loop? For this example would setting the program up as a scheduled task, to be run every minute, not be more economical?
Why don't you write a small application and use the system's task scheduler to run it every minute, hour...etc?
Another option would be to write a Windows Service which runs in the background. The service could use a simple Alarm class like the following on MSDN:
http://msdn.microsoft.com/en-us/library/wkzf914z%28v=VS.90%29.aspx#Y2400
You can use it to periodically trigger your method. Internally this Alarm class uses a timer:
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Just set the timer's interval correctly (e.g. 60000 milliseconds) and it will raise the Elapsed event periodically. Attach an event handler to the Elapsed event to perform your task. No need to implement an "infinite loop" just to keep the application alive. This is handled for you by the service.
I did this for an application that had to process files as they were dropped on a folder. Your best bet is a timer (as suggested) with a Console.ReadLine() at the end of "main" without putting in a loop.
Now, your concern about telling the app to stop:
I have also done this via some rudimentary "file" monitor. Simply creating the file "quit.txt" in the root folder of the application (by either my program or another application that might request it to stop) will make the application quit. Semi-code:
<do your timer thing here>
watcher = new FileSystemWatcher();
watcher.Path = <path of your application or other known accessible path>;
watcher.Changed += new FileSystemEventHandler(OnNewFile);
Console.ReadLine();
The OnNewFile could be something like this:
private static void OnNewFile(object source, FileSystemEventArgs e)
{
if(System.IO.Path.GetFileName(e.FullPath)).ToLower()=="quit.txt")
... remove current quit.txt
Environment.Exit(1);
}
Now you mentioned that this is (or could be) for a mobile application? You might not have the file system watcher. In that case, maybe you just need to "kill" the process (you said "In special situations (like: updating the app), I need to request the app to stop". Whoever the "requester" to stop it is, should simply kill the process)
It sounds to me like you want Main() to enter an interruptable loop. For this to happen, multiple threads must be involved somewhere (or your loop must poll periodically; I am not discussing that solution here though). Either another thread in the same application, or a thread in another process, must be able to signal to your Main() loop that it should terminate.
If this is true, then I think you want to use a ManualResetEvent or an EventWaitHandle . You can wait on that event until it is signalled (and the signalling would have to be done by another thread).
For example:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
startThreadThatSignalsTerminatorAfterSomeTime();
Console.WriteLine("Waiting for terminator to be signalled.");
waitForTerminatorToBeSignalled();
Console.WriteLine("Finished waiting.");
Console.ReadLine();
}
private static void waitForTerminatorToBeSignalled()
{
_terminator.WaitOne(); // Waits forever, but you can specify a timeout if needed.
}
private static void startThreadThatSignalsTerminatorAfterSomeTime()
{
// Instead of this thread signalling the event, a thread in a completely
// different process could do so.
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
_terminator.Set();
});
}
// I'm using an EventWaitHandle rather than a ManualResetEvent because that can be named and therefore
// used by threads in a different process. For intra-process use you can use a ManualResetEvent, which
// uses slightly fewer resources and so may be a better choice.
static readonly EventWaitHandle _terminator = new EventWaitHandle(false, EventResetMode.ManualReset, "MyEventName");
}
}
You can use Begin-/End-Invoke to yield to other threads. E.g.
public static void ExecuteAsyncLoop(Func<bool> loopBody)
{
loopBody.BeginInvoke(ExecuteAsyncLoop, loopBody);
}
private static void ExecuteAsyncLoop(IAsyncResult result)
{
var func = ((Func<bool>)result.AsyncState);
try
{
if (!func.EndInvoke(result))
return;
}
catch
{
// Do something with exception.
return;
}
func.BeginInvoke(ExecuteAsyncLoop, func);
}
You would use it as such:
ExecuteAsyncLoop(() =>
{
// Do something.
return true; // Loop indefinitely.
});
This used 60% of one core on my machine (completely empty loop). Alternatively, you can use this (Source) code in the body of your loop:
private static readonly bool IsSingleCpuMachine = (Environment.ProcessorCount == 1);
[DllImport("kernel32", ExactSpelling = true)]
private static extern void SwitchToThread();
private static void StallThread()
{
// On a single-CPU system, spinning does no good
if (IsSingleCpuMachine) SwitchToThread();
// Multi-CPU system might be hyper-threaded, let other thread run
else Thread.SpinWait(1);
}
while (true)
{
// Do something.
StallThread();
}
That used 20% of one core on my machine.
To expound on a comment CodeInChaos made:
You can set a given thread's priority. Threads are scheduled for execution based on their priority. The scheduling algorithm used to determine the order of thread execution varies with each operating system. All threads default to "normal" priority, but if you set your loop to low; it shouldn't steal time from threads set to normal.
The Timer approach is probably your best bet, but since you mention Thread.Sleep there is an interesting Thread.SpinWait or SpinWait struct alternative for similar problems that can sometimes be better than short Thread.Sleep invocations.
Also see this question: What's the purpose of Thread.SpinWait method?
Lots of "advanced" answers here but IMO simply using a Thread.Sleep(lowvalue) should suffice for most.
Timers are also a solution, but the code behind a timer is also an infinity loop - I would assume - that fires your code on elapsed intervals, but they have the correct infinity-loop setup.
If you need a large sleep, you can cut it into smaller sleeps.
So something like this is a simple and easy 0% CPU solution for a non-UI app.
static void Main(string[] args)
{
bool wait = true;
int sleepLen = 1 * 60 * 1000; // 1 minute
while (wait)
{
//... your code
var sleepCount = sleepLen / 100;
for (int i = 0; i < sleepCount; i++)
{
Thread.Sleep(100);
}
}
}
Regarding how the OS detects if the app is unresponsive. I do not know of any other tests than on UI applications, where there are methods to check if the UI thread processes UI code. Thread sleeps on the UI will easily be discovered. The Windows "Application is unresponsive" uses a simple native method "SendMessageTimeout" to see detect if the app has an unresponse UI.
Any infinity loop on an UI app should always be run in a separate thread.
To keep console applications running just add a Console.ReadLine() to the end of your code in Main().
If the user shouldn't be able to terminate the application you can do this with a loop like the following:
while (true){
Console.ReadLine();
}