How i can get Process.waitForFinish() - c#

I'm trying to get the pid of a process when the process end working but not yet killing.
process.WaitForExit();
the method above stop until the process is killed, but i'm looking for something like process.waitForFinish because i'm trying to handle the process when it finishing working but not yet killed.
Like adding a signal and get in the other process. exemple:
//Process to catch
main(){
//Do some Code
End of the function
SendEndSignal(); & Stop();
}
Second process will catch first process like that
main(){
int pid = Process.start("Process1.exe");
process.waitUntilReceiveSignal();
//Do code here
process.kill();
}
I need something like process.WaitForInputIdle(); but the problem here is it working only if the process contain graphical interface. So what about if the process wait for input from user by console like using Console.readLine().
This mean that i need to know when the process go to inactive state but not killed.

EventWaitHandle is a way to go in your case.
namespace A
{
class Program
{
static void Main(string[] args)
{
var evh = new EventWaitHandle(false, EventResetMode.AutoReset,"fromA");
Console.WriteLine("Anykey to send signal");
Console.ReadKey();
evh.Set();
}
}
}
namespace B
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Waiting for a signal");
var evh = EventWaitHandle.OpenExisting("fromA");
evh.WaitOne();
Console.WriteLine("Signal!");
Console.ReadKey();
}
}
}
But keep in mind you will need to wait for child process to register its EventWaitHandle. So you either do wait for some time (ugly). Or create another EventWaitHandle in parent process, so child process notifies when its handler is registered
Edit: Complete solution
namespace Parent
{
class Program
{
static void Main(string[] args)
{
using (var childReadyEh =new EventWaitHandle(false, EventResetMode.AutoReset,"childIsReady"))
{
Process.Start("child.exe");
childReadyEh.WaitOne();
}
using (var childSignalEh =EventWaitHandle.OpenExisting("childSignal"))
{
childSignalEh.WaitOne();
}
Console.WriteLine("Signal is recieved");
Console.ReadKey();
}
}
}
namespace Child
{
class Program
{
static void Main(string[] args)
{
EventWaitHandle childSignalEh =null;
using (var childReadyEh =EventWaitHandle.OpenExisting("childIsReady"))
{
childSignalEh =new EventWaitHandle(false, EventResetMode.AutoReset,"childSignal");
childReadyEh.Set();
}
Console.WriteLine("Anykey to send a signal to parent");
Console.ReadKey();
childSignalEh.Set();
childSignalEh.Dispose();
Console.WriteLine("Signal is sent");
Console.ReadKey();
}
}
}

Related

The simplest possible infinitely repeat

I need the simplest possible Timer to repeat my code infinitely every 5 seconds. No external classes or whatnot.
Just:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
}
}
How can I do that?
Use while(true) with Thread.Sleep
using System.Threading;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
while(true)
{
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
Thread.Sleep(5000);
}
}
}
Simplest form of it :
using System.Threading;
static void Main(string[] args)
{
bool breakConditionFlag = false;
ManualResetEvent waitHandler = new ManualResetEvent(false);
while(breakConditionFlag)
{
//Your Code
waitHandler.WaitOne(TimeSpan.FromMilliseconds(1000)); // 1000 is the Arbitary value you can change it to Suit your purpose;
}
}
Why ManualResetEvent ?
The event makes more efficient use of the processors- you're not having to wake the parent thread up to poll. The kernel will wake you up when the event fires.
Use Timer.
static void Main(string[] args)
{
Timer timer = new System.Threading.Timer((e) =>
{
Console.WriteLine("Now the following code will be repeated over and over");
}, null, 0, (int)TimeSpan.FromSeconds(5).TotalMilliseconds);
Console.Read();
}
Here I have called Console.WriteLine multiple times, you can write your code block instead of it.
You can use Thread.Sleep(5000); But again its also external class according to the OP.
But I would suggest a better solution using Async and Await. One more thing you should have a termination condition, so that you dont produce an infinite call to avoid unnecessary memory consumption.
public static async Task RepeatActionEveryInterval(Action action, TimeSpan interval, CancellationToken cancelToken)
{
while (true)
{
action();
Task task = Task.Delay(interval, cancelToken);
try
{
await task;
}
catch (TaskCanceledException)
{
return;
}
}
}
static void Main(string[] args)
{
CancellationTokenSource cancelToken = new CancellationTokenSource(TimeSpan.FromSeconds(50));
Console.WriteLine("Start");
RepeatActionEveryInterval(() => Console.WriteLine("Repeating Code"), TimeSpan.FromSeconds(5), cancelToken.Token).Wait();
Console.WriteLine("End");
Console.Read();
}
In this example this code will write till 50 seconds.
Use this code for call your function recursively for every 5 seconds.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace recurssiveWithThread
{
class Program
{
static void Main(string[] args)
{
RecWork();
}
public static int i = 0;
public static void RecWork()
{
// Do the things whatever you needed here
i++;
Console.WriteLine(i);
//Thread to make the process to sleep for sometimes
Thread.Sleep(5000);
//Call your function here
RecWork();
}
}
}
Use BackgroundWorker class:
Reference links:
Background worker
If you are using framework >= 4.5.2 QueueBackgroundWorkItem
QueueBackgroundWorkItem

Run a windows form while my console application still running

I'm new at C# programming and i'm lost with a thing that could be simple.
Executing a console application, at a moment i need to call a Windows Form that will show statics of the execution but when i call the form1.ShowDialog(); this stop the console runtime.
How do i keep my console execution alive while i show a Windows form screen ?
class Program
{
static Form1 form = new Form1();
public static bool run = true;
static void Main(string[] args)
{
work();
}
public static void work()
{
form.Show();
while (run)
{
Console.WriteLine("Console still running");
}
}
}
try this it work on me
using System.Windows.Forms;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
public static bool run = true;
static void Main(string[] args)
{
Startthread();
Application.Run(new Form1());
Console.ReadLine();
}
private static void Startthread()
{
var thread = new Thread(() =>
{
while (run)
{
Console.WriteLine("console is running...");
Thread.Sleep(1000);
}
});
thread.Start();
}
}
}
Threading is like "process inside a process" in my own understanding.
See this question. You have to use Form1.Show() because Form1.ShowDialog() pauses execution until the form is closed.
Update This seems to be working (with Application.Run):-
public static Form1 form = new Form1();
public static bool run = true;
[MTAThread]
static void Main(string[] args)
{
new Thread(() => Application.Run(form)).Start();
new Thread(work).Start();
}
public static void work()
{
while (run)
{
Console.WriteLine("Console Running");
}
}

Starting a GameWindow in a thread

I'm trying to write an OpenTK application where you can type commands in a console window, and have a GameWindow display the result of commands.
My code looks like this:
public Program : GameWindow
{
static void Main(string[] args)
{
var display = new Program();
var task = new Task(() => display.Run());
task.Start();
while (true)
{
Console.Write("> ");
var response = Console.ReadLine();
//communicate with the display object asynchronously
}
}
}
However, the display window does not appear when started in a task or thread.
Why is this the case? I need the Run method to happen in a thread, because it is blocking for the life of the window.
To fix your particular problem, just create instance of your window ("display" in your case) on thread itself:
public class Program : GameWindow {
private static void Main(string[] args) {
Program display = null;
var task = new Thread(() => {
display = new Program();
display.Run();
});
task.Start();
while (display == null)
Thread.Yield(); // wait a bit for another thread to init variable if necessary
while (true)
{
Console.Write("> ");
var response = Console.ReadLine();
//communicate with the display object asynchronously
display.Title = response;
}
}
}

Mutex Console Release

This is a console application Wqhen i run the below program it shows a single console
and i have executed 3 other console from bin directory now my question is
When 1 console is has been has completed its task . Control is not going to other console
it is showing the same display Running(Console 1). How does Running show on other consoles.
class Program
{
static Mutex m = new Mutex(true, "demo");
public static void Main()
{
if (!m.WaitOne(1000))
{
Console.WriteLine("another");
Console.ReadLine();
}
else
{
try
{
run();
}
finally
{
m.ReleaseMutex();
}
}
}
public static void run()
{
Console.WriteLine("running");
Console.ReadLine();
Thread.Sleep(1000);
m.ReleaseMutex();
}
}
your program would be getting stuck due to readline where it holds for user input, try to use mutex like eg below
using (var mutex = new Mutex(false, "demo"))
{
mutex.WaitOne();
run();
mutex.ReleaseMutex();
}

Non-terminating / non-blocking Windows Mobile App

I have a console app that I want to run continually in the background. I thought that if I started it up and then told it to wait things would work. But when I have it wait, it freezes the application.
Here is my code:
class Program
{
static public ManualResetEvent StopMain;
static void Main(string[] args)
{
// Hide the cursor.
Cursor.Current = Cursors.Default;
StopMain = new ManualResetEvent(false);
RunHook runHook = new RunHook();
// wait until signalled by Program.StopMain.Set();
StopMain.WaitOne();
}
}
class RunHook
{
private HookKeys hook;
public RunHook()
{
hook = new HookKeys();
hook.HookEvent += EventForHook;
}
private void EventForHook(HookEventArgs e, KeyBoardInfo keyBoardInfo,
ref Boolean handled)
{
if ((keyBoardInfo.scanCode == 4) && (keyBoardInfo.vkCode == 114))
handled = true;
}
}
Any ideas on how to have this run in the background but never terminate?
The behavior you see is expected. You have one thread, and it's in a wait state. To get some form of activity, you have to let the scheduler actually do something. A background thread is one way to achieve this:
static void Main(string[] args)
{
StopMain = new ManualResetEvent(false);
bool exit = false;
new Thread(
delegate
{
new RunHook();
while(!exit) { Thread.Sleep(1); }
}
).Start();
StopMain.WaitOne();
exit = true;
}
Another is to just let the primary thread yield:
static void Main(string[] args)
{
StopMain = new ManualResetEvent(false);
RunHook runHook = new RunHook();
while(!StopMain.WaitOne())
{
Thread.Sleep(1);
}
}
There are certainly other ways, too. Personally I'd do neither of these. Instead I'd add a blocking method to the RunHook class and have it return when it was done or signalled.

Categories