c# Using Process.start () efficiently
You could spawn a bunch of tasks and do a Task.WaitAll, as shown in Matt Burland's answer.
A few other options are as follows. (I haven't tested these too thoroughly so you'll probably want to do so). First, you could use an event instead of WaitForExit:
private int counter = 0;
int sumOfImages = 10; // Set this to the number of files
private void ProcessStart(List<string> files)
{
foreach (string file in files)
{
Process process = new Process();
process.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "someCommand";
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;
process.Exited += Process_Exited;
process.Start();
}
}
private void Process_Exited(object sender, EventArgs e)
{
int result = Interlocked.Increment(ref counter);
int percentComplete = ((result / sumOfImages) * 100);
worker.ReportProgress(percentComplete);
}
You could, if you wanted, put the whole thing on the Thread Pool. I actually like this as an answer - the CPU-bound part of this is creating and starting the processes and that would put that on a background thread so it wouldn't hang your UI. It would eliminate the overhead of waiting for a result, which isn't CPU-bound.
Here's an illustration. Suppose you go to a restaurant with 10 people. When the waiter comes, 9 out of the 10 people are ready to order. The waiter happens to ask that guy for his order first. At this point, everyone at the table could either wait around for him to decide or the waiter can take orders from the 9 other people at the table and come back to the first guy. Odds are it would be rather pointless to bring in an additional waiter to wait for the first guy's order while the original waiter takes the other 9 orders. If absolutely necessary the waiter could take the 9 orders to the kitchen and come back to take the first guy's order.
Point being that if it's just a matter of waiting for results from one of the people bringing in additional waiters isn't necessarily going to give you much of a performance boost.
Obviously in this analogy the waiter is a thread and the people are tasks that need to be accomplished. In the above solution, you have a single waiter (the Thread Pool thread) service all of the people (create all of the processes) and then the people (processes) tell him when they're ready to order (i.e. the process raises the event). He then tells the kitchen their order (raises the ReportProgress event on the Worker).
Another option would be a Parallel.ForEach loop:
private void ProcessStart(List<string> files)
{
int sumOfImages = files.Count;
int count = 0;
string command = "";
Parallel.ForEach(files,
delegate (string file)
{
Process process = new Process();
process.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = command;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
int result = Interlocked.Increment(ref count);
int percentComplete = ((result / sumOfImages) * 100);
worker.ReportProgress(percentComplete);
});
}
How to start a Process c# Not working
>
is not an argument, it's a shell operator. Since you're "passing" it wrong, and since you disabled UseShellExecute
, this isn't going to work.
You'll need to do the redirection manually :)
Also, once you say "sure, redirect output and error to me", you have to actually read those streams. If you don't, the application is going to hang when it runs out of space in the output buffers. This is likely why your code mysteriously stopped working - the guest application is writing more than the buffers can handle.
Start A Process With Parameters
You can use this:
Process.Start("MyExe.exe", "arguments");
C# - Start a process in background
If i understand right your question, you would run process without interface.
Try that code
var info = new ProcessStartInfo ( path , arguments )
{
Domain = processConfiguration.Domain ,
Password = password ,
UserName = processConfiguration.UserName ,
RedirectStandardOutput = true ,
UseShellExecute = false ,
CreateNoWindow = true
} ;
System.Diagnostics.Process proc = new System.Diagnostics.Process () ;
proc.StartInfo = info ;
proc.Start () ;
How can I start a new Process and wait until it finishes?
After you call Start()
add: Process.WaitForExit()
var myProcess = new Process {StartInfo = new ProcessStartInfo(processPath)};
myProcess.Start().WaitForExit();
Start a process in the same console
You shouldn't need to do anything other than set UseShellExecute = false
, as the default behaviour for the Win32 CreateProcess function is for a console application to inherit its parent's console, unless you specify the CREATE_NEW_CONSOLE flag.
I tried the following program:
private static void Main()
{
Console.WriteLine( "Hello" );
var p = new Process();
p.StartInfo = new ProcessStartInfo( @"c:\windows\system32\netstat.exe", "-n" )
{
UseShellExecute = false
};
p.Start();
p.WaitForExit();
Console.WriteLine( "World" );
Console.ReadLine();
}
and it gave me this output:
Related Topics
Difference Between Property and Field in C# 3.0+
What Are the Correct Version Numbers For C#
All Possible Array Initialization Syntaxes
How to Make the Script Wait/Sleep in a Simple Way in Unity
What Is a Good Pattern For Using a Global Mutex in C#
Nesting Await in Parallel.Foreach
Encrypting & Decrypting a String in C#
How to Create a Dropdownlist from an Enum in ASP.NET MVC
Output Log Using Ftpwebrequest
Creating a Byte Array from a Stream
How to Escape a Double Quote in a Verbatim String Literal
Why Is Floating Point Arithmetic in C# Imprecise
How to Convert Json Object to Custom C# Object
One Dbcontext Per Web Request... Why
How to Specify a [Dllimport] Path At Runtime