Reputation: 40
I have a Webapplication for News and also some Guides.
In the backend you have the function that you can upload multiple images with no limit, cause of pagination.
The Controller runs after the image was successfully added to the entry an ImageOptimizer Task for JPEG and for PNG.
I made a big stress test today and well my memory was at 100% usage because the processes were running all at the same time.
My question is: Is it possible to let the ProcessStart wait until the same executable ended? That would help a lot :-)
The Code for starte the task is pasted below. So I use simple the ProccessStart Cls in C#.
public static string Do(string path, bool clientMode = false)
{
/** I want to do something like this:**/
while(ThisExecutableIsAllreadyRunning);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendFormat("Optimizing \"{0}\"", path).AppendLine();
long length = new FileInfo(path).Length;
stringBuilder.AppendFormat("Size before: {0}", length).AppendLine();
string text = "~/Executables/optipng.exe";
if (clientMode)
{
if (String.IsNullOrEmpty(ClientModeExecutablePath))
throw new Exception("Client Mode for IMG Optim required ClientModeExecutablePath to be set");
text = ClientModeExecutablePath;
}
else
text = HttpContext.Current.Server.MapPath(text);
Process process = Process.Start(text, "-strip all " + path);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string value = process.StandardOutput.ReadLine();
stringBuilder.AppendLine(value);
}
length = new FileInfo(path).Length;
stringBuilder.AppendFormat("Size After: {0}", length).AppendLine();
stringBuilder.AppendLine("Done...");
return stringBuilder.ToString();
}
Upvotes: 0
Views: 789
Reputation: 1916
Here's how you can check if a particular exe application is already running due to some other thread or process:
using System.Diagnostics;
//get all currently running applications
var allProcesses = Process.GetProcesses().ToList();
//filter out the processes that don't match the exe you're trying to launch
foreach(var process in allProcesses.Where(p => p.Modules[0].FileName.ToLower().EndsWith(ClientModeExecutablePath.ToLower())))
{
try
{
Console.WriteLine("Process: {0} ID: {1}, file:{2}", process.ProcessName, process.Id, process.Modules[0].FileName);
//wait for the running process to complete
process.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine (ex);
}
//now launch your process
//two threads could still launch the process at the same time after checking for any running processes
}
Upvotes: 1
Reputation:
Is it possible to let the ProcessStart wait untill the same executable ended?
Certainly. If I have understood you correctly you want to wait for the process to exit until continuing. Try this code:
Process process = Process.Start(text, "-strip all " + path);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = false;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string value = process.StandardOutput.ReadLine();
stringBuilder.AppendLine(value);
}
process.WaitForExit(); // <-------- WAIT HERE
MSDN:
Instructs the Process component to wait indefinitely for the associated process to exit. WaitForExit() makes the current thread wait until the associated process terminates. It should be called after all other methods are called on the process. To avoid blocking the current thread, use the Exited event.
It's hard to tell if your Do()
method is being called concurrently or not. If so you may want to protect it with some form of lock()
or critical section to ensure only one process is spawned at a time. This places the guard in the instigator.
Alternatively you could create a named mutex in the .EXE. If it was found that the mutex previously exited you should immediately exit. This places the guard in the action.
Good luck!
Upvotes: 1