在c#中将进程的实例限制为1

本文关键字:实例 进程 | 更新日期: 2023-09-27 18:02:39

我目前有一个大问题,下面的代码检查文件中的关键字"mp4:production/CATCHUP/",如果发现它将启动一个可执行文件,尽管因为它发现了多个(完全相同的)"mp4:production/CATCHUP/"的实例,它启动了几个进程。有没有什么办法来限制它,以便它在发现一个实例时停止查找?

我的代码如下:
string s = "";
        private void CheckLog()
        {
            bool _found;
            while (true)
            {
                _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("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();
                }
            }
        }

在c#中将进程的实例限制为1

对于这个场景,我将使用Singleton类来管理工作流。Singleton将以全局线程安全的方式管理相当于_found的变量。所有线程都将查询此属性。

类似如下:

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;
      }
   }
}

那么你的代码应该像下面这样:

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();
        }
    }
}

正如Hans Passant所建议的,一旦找到循环就停止循环的方法有什么问题?不需要单例

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
        }
    }
}