dotnet 判斷特定進程存在方法
- 2019 年 10 月 8 日
- 筆記
本文告訴大家幾個方法判斷特定的進程是否存在,同時對比這些方法的性能
使用鎖判斷
在 C# 中判斷一個進程存在的方法,如果這個進程是自己創建的,可以通過 Mutex 的方法,通過創建一個鎖,然後在其他進程判斷這個鎖是否存在。這使用到內核的方法,性能不錯
假設需要判斷進程 HacurbonefeciloQicejewarrerai 是否存在,而這個進程是自己寫的進程,那麼可以在這個進程的主函數創建一個鎖請看程式碼
class Program { static void Main(string[] args) { var mutex = new Mutex(true, Const.Lock, out var createdNew); if (!createdNew) { Console.WriteLine("已經有進程啟動"); } Console.ReadKey(); mutex.Dispose(); } } public static class Const { public const string Lock = "5742D257-CCCC-4F7A-2191-6362609C452D"; }
在另一個進程可以使用下面方法判斷進程是否已經存在
public bool FindExistByMutex() { return Mutex.TryOpenExisting(Const.Lock, out var result); }
在使用 Mutex 如果沒有傳入 Name 那麼將會在一個進程內,使用相同對象的鎖,做到同步。如果給了命名,將會調用內核,在所有進程同步
使用鎖判斷進程存在將需要小心這些問題 .NET 中使用 Mutex 進行跨越進程邊界的同步 – walterlv
使用進程名判斷
另一個方法是通過進程名判斷,這樣判斷的進程就不需要是自己寫的進程,通過進程名判斷是獲取對應進程名的進程,通過判斷返回數組元素,請看程式碼
public bool FindExistByProcessName() { var name = "HacurbonefeciloQicejewarrerai"; return Process.GetProcessesByName(name).Length > 0; }
上面程式碼的 name 傳入需要判斷的進程
在使用進程名判斷的時候,可選的方法還有通過 Process.GetProcesses()
然後判斷裡面的進程名,但是使用上面方法的性能是最高的
使用 Process 判斷進程是否存在的方法性能請看 .NET 中 GetProcess 相關方法的性能 – walterlv
現在已經告訴大家兩個方法判斷進程是否存在,通過內核方式判斷的性能比較快,請看下面性能
兩個方法性能
使用標準性能測試 測試了兩個方法的性能,可以看到使用內核的方式的性能很快
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362 Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores [Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.4010.0 DefaultJob : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.4010.0
Method |
Mean |
Error |
StdDev |
---|---|---|---|
FindExistByProcessName |
6,955.411 us |
197.9235 us |
580.4753 us |
FindNotExistByProcessName |
6,552.935 us |
198.3320 us |
271.4790 us |
FindExistByMutex |
3.032 us |
0.0908 us |
0.2649 us |
FindNotExistByMutex |
2.064 us |
0.0412 us |
0.0521 us |
測試程式碼請看下面
public class Program { static void Main(string[] args) { BenchmarkRunner.Run<Program>(); } [Benchmark] public bool FindExistByProcessName() { var name = "HacurbonefeciloQicejewarrerai"; return Process.GetProcessesByName(name).Length > 0; } [Benchmark] public bool FindNotExistByProcessName() { return Process.GetProcessesByName("不存在的進程").Length > 0; } [Benchmark] public bool FindExistByMutex() { return Mutex.TryOpenExisting(Const.Lock, out var result); } [Benchmark] public bool FindNotExistByMutex() { return Mutex.TryOpenExisting("不存在的進程", out var result); } }
在運行測試程式碼之前先使用下面程式碼測試判斷進程存在
static void Main(string[] args) { Process.Start("HacurbonefeciloQicejewarrerai.exe"); var program = new Program(); Console.WriteLine($"FindExistByProcessName={program.FindExistByProcessName()}"); Console.WriteLine($"FindNotExistByProcessName={program.FindNotExistByProcessName()}"); Console.WriteLine($"FindExistByMutex={program.FindExistByMutex()}"); Console.WriteLine($"FindNotExistByMutex={program.FindNotExistByMutex()}"); }
程式碼放在 github 歡迎下載