I am opening an executable from a C# program, which add some information to a Memory Mapped File. How could I signal the parent process that the information was added into the MMF and it can read it? The child process will be killed as soon as the parent read from the MMF.
I did try to set the Exited event on the process, but this is not a good solution, because I don't want my child process to close until the parent didn't read the information from the file. I set the parent process to WaitForExit() (to wait for the child process to finish), so it doesn't start reading from the MMF while the child didn't finish, but also I don't want a finish signal of the child process, I just want a signal that it added the info to the MMF.
How could I solve this?
There are several ways to signal the parent process that the child process has added information to the Memory Mapped File (MMF) and it can be read:
Use a semaphore: The child process can acquire a semaphore before writing to the MMF and release it after the write operation is complete. The parent process can wait on the semaphore and then proceed to read from the MMF after it is released.
Use a named event: The child process can create a named event before writing to the MMF and set it after the write operation is complete. The parent process can wait on the named event and then proceed to read from the MMF after it is set.
Use a shared variable: The child process can write to a shared variable before writing to the MMF and signal the parent process after the write operation is complete. The parent process can check the shared variable before reading from the MMF.
Use a Named Pipe: The child process can write to the named pipe after writing to the MMF and signal the parent process. the parent process can read from the pipe and proceed to read from the MMF.
Related
I have a process that I would like to be able to cleanly shut down from an external process. That is, I would like to give it a chance to clean up it's resources (save it's data etc.) before it dies.
Process.CloseMainWindow appears to be the ordinary way to go, except the process in question doesn't have any windows and I don't want to immediately call Process.Kill because I want to give it chance to clean up first (and a kill process command can't be intercepted by the target process).
So what is the best way to allow my process to be shut cleanly from another process?
I have control over both processes. The process to be shut does have a message loop (Application.Run()) so I would think there would be some message I could post through there.
I have read the msdn article on terminating processes and this article about closing processes cleanly however both mention methods that seem quite sophisticated despite the simplicity of what I am trying to achieve. Given that I have control over both processes I am hoping there's something a bit simpler that can be implemented cleanly in C#. Is there one?
The process to close is not a service, so can't do service stop.
I'm not sure if a .NET message loop supports thread messages, or only window messages. If it supports thread messages, then the terminating app can use PostThreadMessage() to post a WM_QUIT message (or a custom message that the message loop can look for) to the main thread of the target process so it can stop its message loop and exit the app.
Otherwise, have the target app create a named kernel event object using EventWaitHandle and then wait on the event, either by calling EventWaitHandle.WaitOne() in a manual thread, or calling ThreadPool.RegisterWaitForSingleObject() to use a system-provided thread pool. When the event is signaled, you can notify the main thread to exit the app. The terminating app can then open the event object by name using EventWaitHandle.OpenExisting(), and then signal the event with EventWaitHandle.Set().
In my application there is a parent process that spawns its children. I am trying to leverage this parent process to watch over the children to ensure that the GUI remains responsive, and if not, generate a dump file.
The problem I'm running into is that Process.Responding is only detecting some GUI hangs (such as sleeping on the GUI thread or a stack overflow) but not others (such as deadlocks on the GUI thread).
So the question is: How else can I check whether or not the GUI of the child is still updating from the parent process?
EDIT: Based on the comments so far I guess I should clarify. I am responsible for maintaining the framework of an application with a plugin architecture that is heavily multi-threaded and has a code base of hundreds of thousands of lines of code, much of which is outside my control. While I understand that the ideal approach is not to hang in the first place, it still happens on occasion. I would like these situations gracefully and collect debug information along the way so that the issue can be addressed.
Another approach I've considered is using the GUI thread to touch a file and have the parent process check the time stamp of the file. However, I'd rather not perform file operations on the GUI thread.
After a few failed attempts with the strategies I mentioned above, here's how I ended up solving this:
At child application start I save a reference to the GUI thread
A timer is started that periodically checks the thread state of the
GUI thread (about every 200ms). If it is ThreadState.Running, I
report the process as responding to the parent through
inter-process communication.
In the parent process I keep a dictionary of the process IDs
and the time the process was last reported as responding. If a
child is still alive but hasn't reported a responding result within
the timeout period, the user is notified that the process is not
responding.
So far, everything seems to be working as I would expect it to.
Here is the situation:
I have to create a program that would input another processes output stream into textbox. That it self wouldn't cause too much problem. What does, however, is the fact that I have to run 5 instances of this console application and redirect output to 5 textboxes, as well as to be able to kill any of these processes at any time. As far as I have learned, the best way to do this is asynchronously. But the problem here is with killing processes, that are created on different thread. How do I kill it without having access to it since it doesn't exist in scope where I have to kill it. My best guess is to get its PID on Process.Start(), so I can kill it, so...
Is it possible to fire any event from process on Process.kill() command?
And if not - is there a way to kill a process in about the same time interval as Process.Kill() that does fire some sort of event?
Or maybe someone could suggest me some other approaches or best practice on how these problems are usually solved?
EDIT: The reason I am running all processes on different threads is that I use Thread.Sleep() on some of them if there is and input parameter that tell me that the process must be killed after x seconds.
Process.Kill() command for some reason, does, in fact, fire process exited event. Easiest way for me to know that the process was killed, was by making a volatile string that holds information about how it ended. (Change it to "killed" before process.kill etc...)
First of all you do not need Threads at all. Starting a process is async in itself, so Process.Start(...) does not block and you can create as many processes as you want.
Instead of using the static Process.Start method you should consider creating Process class instances and set the CanRaiseEvents property to true. Further there are a couple of events you can register (per instance) - those will only raise if CanRaiseEvents is set to true, but also after a process is/has exited (including Kill() calls).
When you call
Process.Start()
it returns a Process class instance, which you can use to retrieve information from it output and kill that process any time
Process p = Process.Start("process.exe");
//some operations with process, may be in another thread
p.Kill()
In have 2 processes, a parent process and a child process. The parent process controls the lifecycle of child process i.e. parent process launches the child process when it needs the child to do some work and also it kills the child when it is done with it. To kill the child process, parent process is using Process.Kill() and process.WaitForExit() APIs.
Questions: -
I am observing that the exit code of the child process is always -1. Who is setting this exit code?
How can I change this exit code?
Process.Kill
No. Unless you pinvoke TerminateProcess() yourself, uExitCode argument.
Have a look at Reflector, this kind of stuff is easy to find with it.
The process exit code is likely being set by Win32. You can't change it. If you want to change the exit code, don't use Process.Kill as your IPC mechanism. Set an event or use other IPC primitives instead.
So i have a helper process written in C++ and I open it, feed it arguments, and it feeds my program back information through the standardoutput stream.
PS. I don't have the source for the helper process exe.
If my application were to be terminated from the task manager, or for some reason crash, how could I ensure that my helper exe is closed? Is this possible? Would I need an external file?
Use Job Objects to manage groups of processes. In this case you want to create a job object using CreateJobObject, use SetInformationJobObject to set the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag, and assign the helper process to the job using AssignProcessToJobObject. Don't close the handle to the job object unless you want to kill the helper process. When your process terminates (through any means), the handle will be closed and your helper process will be killed.
You should create an inheritable duplicate of the parent process handle and pass its value to the helper process on the commandline. The helper process can then wait on that handle on a separate thread (or the main thread if you're clever). When the handle becomes signaled, it means that the launching process has terminated.
Edit
Since you can't change the helper process, your options are more limited. Your could try attaching a handler to the launching process's OnAppDomainUnloaded event, but I'm not sure this will work in all the cases you're concerned about. You could also create a third process to monitor the first. This process would work as I described above. If you wanted to get really fancy, you could inject a remote thread into the helper process to monitor the parent. This is very technical, so I recommend against it.
The easiest way would be to close it on normal application exit and when AppDomain.CurrentDomain.UnhandledException is invoked (i.e. your app is about to crash)