91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用C#怎么守護Python進程

發布時間:2021-05-19 16:37:23 來源:億速云 閱讀:187 作者:Leah 欄目:編程語言

這篇文章給大家介紹使用C#怎么守護Python進程,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

實現#

對于我們的系統而言,我們的 Python 進程只允許存在一個,因此,對應的服務類型要采用單例模式,這一部分代碼相對簡單,就直接貼出來了,示例代碼如下所示:

public partial class PythonService
{
 private static readonly object _locker = new object();

 private static PythonService _instance;
 public static PythonService Current
 {
 get
 {
 if (_instance == null)
 {
 lock (_locker)
 {
 if (_instance == null)
 {
 _instance = new PythonService();
 }
 }
 }
 return _instance;
 }
 }

 private PythonService()
 {

 }
}

創建獨立進程#

由于后端的 Python 代碼運行需要安裝一些第三方的擴展庫,所以為了方便,我們采用的方式是總結將 python 安裝文件及擴展包和他們的代碼一并打包到我們的項目目錄中,然后創建一個 Python 進程,在該進程中通過設置環境變量的方式來為 Python 進程進行一些環境配置。示例代碼如下所示:

public partial class PythonService
{
 private string _workPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scripts");
 private string _pythonPath => Path.Combine(_workPath, "python27");

 private bool isRunning = false;
 private int taskPID = -1;

 public void Start()
 {
 taskPID = CreateProcess();
 isRunning = taskPID != -1;

 var msg = isRunning ? "服務啟動成功..." : "服務啟動失敗...";
 Trace.WriteLine(msg);
 }

 public void Stop()
 {
 KillProcessAndChildren(taskPID);

 isRunning = false;
 taskPID = -1;
 }

 private int CreateProcess()
 {
 KillProcessAndChildren(taskPID);

 int pid = -1;
 var psi = new ProcessStartInfo(Path.Combine(_pythonPath, "python.exe"))
 {
 UseShellExecute = false,
 WorkingDirectory = _workPath,
 ErrorDialog = false
 };

 psi.CreateNoWindow = true;

 var path = psi.EnvironmentVariables["PATH"];
 if (path != null)
 {
 var array = path.Split(new[] { ';' }).Where(p => !p.ToLower().Contains("python")).ToList();
 array.AddRange(new[] { _pythonPath, Path.Combine(_pythonPath, "Scripts"), _workPath });
 psi.EnvironmentVariables["PATH"] = string.Join(";", array);
 }
 var ps = new Process { StartInfo = psi };
 if (ps.Start())
 {
 pid = ps.Id;
 }
 return pid;
 }

 private static void KillProcessAndChildren(int pid)
 {
 // Cannot close 'system idle process'.
 if (pid <= 0)
 {
 return;
 }

 ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
 ManagementObjectCollection moc = searcher.Get();
 foreach (ManagementObject mo in moc)
 {
 KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
 }
 try
 {
 Process proc = Process.GetProcessById(pid);
 proc.Kill();
 }
 catch (ArgumentException)
 {
 // Process already exited.
 }
 catch (Win32Exception)
 {
 // Access denied
 }
 }
}

這里有一點需要注意一下,建議使用 PID 來標識我們的 Python 進程,因為如果你使用進程實例或其它方式來對當前運行的進程設置一個引用,當該進程出現一些未知退出,這個時候你通過哪個引用來進行相關操作是會出問題的。

創建守護進程#

上面我們的通過記錄當前正在運行的進程的 PID 來標識我們的進程,那對應守護進程,我們就可以通過進程列表查詢的方式來進行創建,在輪詢的過程中,如果未找到對應 PID 的進程則表明該進程已經退出,需要重新創建該進程,否則就不執行任何操作,示例代碼如下所示:

public partial class PythonService
{
 private CancellationTokenSource cts;

 private void StartWatch(CancellationToken token)
 {
 Task.Factory.StartNew(() =>
 {
  while (!token.IsCancellationRequested)
  {
  var has = Process.GetProcesses().Any(p => p.Id == taskPID);
  Trace.WriteLine($"MQ狀態:{DateTime.Now}-{has}");
  if (!has)
  {
   taskPID = CreateProcess(_reqhost, _subhost, _debug);
   isRunning = taskPID > 0;

   var msg = isRunning ? "MQ重啟成功" : "MQ重啟失敗,等待下次重啟";
   Trace.WriteLine($"MQ狀態:{DateTime.Now}-{msg}");
  }

  Thread.Sleep(2000);
  }
 }, token);
 }
}

這里我使用的是 Thread.Sleep(2000) 方式來繼續線程等待,你也可以使用 await Task.Delay(2000,token),但是使用這種方式在發送取消請求時會產生一個 TaskCanceledException 的異常。所以為了不產生不必要的異常信息,我采用第一種解決方案。

接著,完善我們的 Start 和 Stop 方法,示例代碼如下所示:

public void Start()
{
 taskPID = CreateProcess();
 isRunning = taskPID != -1;

 if (isRunning)
 {
 cts = new CancellationTokenSource();
 StartWatch(cts.Token);
 }

 var msg = isRunning ? "服務啟動成功..." : "服務啟動失敗...";
 Trace.WriteLine(msg);
}

public void Stop()
{
 cts?.Cancel(false);
 cts?.Dispose();

 KillProcessAndChildren(taskPID);
 taskPID = -1;

 isRunning = false;
}

C#是什么

C#是一個簡單、通用、面向對象的編程語言,它由微軟Microsoft開發,繼承了C和C++強大功能,并且去掉了一些它們的復雜特性,C#綜合了VB簡單的可視化操作和C++的高運行效率,以其強大的操作能力、優雅的語法風格、創新的語言特性和便捷的面向組件編程從而成為.NET開發的首選語言,但它不適用于編寫時間急迫或性能非常高的代碼,因為C#缺乏性能極高的應用程序所需要的關鍵功能。

關于使用C#怎么守護Python進程就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

左贡县| 新乡市| 罗江县| 扎赉特旗| 洪雅县| 咸宁市| 陆丰市| 万安县| 东宁县| 颍上县| 潞城市| 黔东| 阳朔县| 井陉县| 马山县| 和顺县| 宝丰县| 德令哈市| 鄂州市| 庄浪县| 交城县| 水城县| 博客| 克东县| 会昌县| 临武县| 若羌县| 库尔勒市| 麻阳| 酉阳| 聂拉木县| 阳泉市| 桓仁| 柳州市| 寿宁县| 安福县| 浦江县| 监利县| 肇源县| 武定县| 浠水县|