Restricting the instance of a process to 1 in C#
I currently have a big problem, the code below checks for the keyword "mp4:production/CATCHUP/" in a file, and if found it will launch an executable, although because it finds multiple (exactly the same) instances of "mp4:production/CATCHUP/" it launches several processes. Is there anyway of restricting this, so that it may stop looking when found one instance?
My code is as follows:
string s = "";
private void CheckLog()
{
bool _found;
while (true)
{
_found = false;
Thread.Sleep(5000);
if (!Sys开发者_C百科tem.IO.File.Exists("Command.bat")) continue;
using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
{
while ((s = sr.ReadLine()) != null)
{
if (s.Contains("test"))
{
_found = true;
break;
}
}
}
if (_found)
{
// Deletes filename in the log file, as the filename is instead handled by p.start
var result = Regex.Replace(s, @"test", string.Empty);
s = result;
RemoveEXELog(); // Deletes a specific keyword from Command.bat
RemoveHostFile();
Process p = new Process();
p.StartInfo.WorkingDirectory = "dump";
p.StartInfo.FileName = "test.exe";
p.StartInfo.Arguments = s;
p.Start();
p.WaitForExit();
MessageBox.Show("Operation Successful!");
string myPath = @"dump";
System.Diagnostics.Process prc = new System.Diagnostics.Process();
prc.StartInfo.FileName = myPath;
prc.Start();
ClearLog(); // Deletes Command.bat and then creates a new empty Command.bat
LogTrue();
}
}
}
For this scenario I would use a Singleton class to manage the workflow. The Singleton would manage the equivalent to your _found
variable in a global threadsafe manner. All threads would then query this property.
Something like the following:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public bool Found { get; set; }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Then your code would be something like the following:
private void CheckLog()
{
//bool _found; //not needed anymore
while (!Singleton.Instance.Found)
{
//_found = false;
Thread.Sleep(5000);
if (!System.IO.File.Exists("Command.bat")) continue;
using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
{
while ((s = sr.ReadLine()) != null)
{
if (s.Contains("mp4:production/CATCHUP/"))
{
Singleton.Instance.Found = true;
break;
}
}
}
if (Singleton.Instance.Found)
{
// Deletes filename in the log file, as the filename is instead handled by p.start
var result = Regex.Replace(s, @"rtmpdump", string.Empty);
s = result;
RemoveEXELog(); // Deletes a specific keyword from Command.bat
RemoveHostFile();
Process p = new Process();
p.StartInfo.WorkingDirectory = "dump";
p.StartInfo.FileName = "test.exe";
p.StartInfo.Arguments = s;
p.Start();
p.WaitForExit();
MessageBox.Show("Operation Successful!");
string myPath = @"dump";
System.Diagnostics.Process prc = new System.Diagnostics.Process();
prc.StartInfo.FileName = myPath;
prc.Start();
ClearLog(); // Deletes Command.bat and then creates a new empty Command.bat
LogTrue();
}
}
}
As suggested by Hans Passant, what is wrong with the obvious stop looping once you'vre found it approach? No singletons required.
private void CheckLog()
{
bool found = false;
while (!found)
{
//your code ...
while ((s = sr.ReadLine()) != null)
{
if (s.Contains("test"))
{
_found = true;
break;
}
}
if (found)
{
//some more of your code ...
}
else
{
//get ready for the next iteration
}
}
}
精彩评论