使用Mutex實現單一程式執行個體的注意事項(转)
相信大家都知道在.NET程式中若要實現單一程式執行個體,一般來說有幾種方法,像是去判斷是否已經有開啟的Process是相同的程式、用Mutex與Semaphore之類的技術來判斷是否程式正在開啟。但是很多網路上的文章都忽略了在用Mutex實現單一程式執行個體時,其實會有些必須要注意的地方,導致於在實際運用上沒有發揮到該有的效果。
以一個簡單的例子來看,一般我們在網路上常看到的使用方式大概就像下面的程式碼片段類似,建構Mutex時就會回傳該Mutex是否已經存在,利用該回傳值來決定程式應該繼續開啟還是關閉。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading; namespace WindowsFormsApplication10
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Boolean bCreatedNew; //Create a new mutex using specific mutex name
Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew); if (bCreatedNew)
Application.Run(new Form1());
}
}
}
這樣的程式到底有什麼樣的問題呢?有興趣的可以試著建置Release的程式看看,其實這樣的程式在某些情況下會在Release模式下失效,Debug的運作卻是正常的,若試不出來的可以再加上個GC.Collect試試,會更容易重現。
...
Boolean bCreatedNew; //Create a new mutex using specific mutex name
Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew); GC.Collect(); if (bCreatedNew)
Application.Run(new Form1());
...
之所以會有這樣的問題,是因為Mutex在Release模式下被GC給回收了,而Debug模式下因為便於開發人員除錯,據說有將GC的周期給拉長,所以不容易重現。那這樣的問題要怎麼樣解決呢?這邊筆者有整理了幾種方法。
一個方法就是把Mutex給拉出來成為類別成員。
...
static Mutex m; /// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Boolean bCreatedNew; //Create a new mutex using specific mutex name
m = new Mutex(false, "myUniqueName", out bCreatedNew);
GC.Collect(); if (bCreatedNew)
Application.Run(new Form1());
}
...
另一個方法就是讓Mutex不要被GC回收掉,像是在程式最後明確呼叫Dispose,讓GC知道該Mutex仍在使用。
...
Boolean bCreatedNew; //Create a new mutex using specific mutex name
Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew); GC.Collect(); if (bCreatedNew)
Application.Run(new Form1()); m.Dispose();
...
也可以用using或是try...finally之類的語法將Mutex給hold住。
...
Boolean bCreatedNew; //Create a new mutex using specific mutex name
using (Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew))
{
GC.Collect(); if (bCreatedNew)
Application.Run(new Form1());
}
...
或是把Mutex的用法寫的比較正規一點,加上WaitOne與ReleaseMutex去明確控制Mutex的作用範圍。
...
Boolean bCreatedNew; //Create a new mutex using specific mutex name
Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew); m.WaitOne();
GC.Collect(); if (bCreatedNew)
Application.Run(new Form1()); m.ReleaseMutex();
...
使用Mutex實現單一程式執行個體的注意事項(转)的更多相关文章
- System.Web.Compilation.BuildManager.CopyPrecompiledFile 並未將物件參考設定為物件的執行個體
使用MSBUild 的 aspnet_compiler.exe 发布网站, 过程中出现错误 [NullReferenceException]: 並未將物件參考設定為物件的執行個體 System.W ...
- linux下c++實現簡單的生產者消費者隊列模式
引言 生產者消費者是一個經典的模式 利用生產者,消費者和緩衝區降低了生產者和消費者之間的的耦合度 便於對生產者和消費者的修改 下面記錄的是一個經典的單一生產者多消費者的模式 設計思路 以隊列做為緩衝區 ...
- (STM32F4) IAP程式碼實現
IAP學習, 主要想了解實際上程式碼放在不同的Flash位置如何轉跳且執行. 我的應用程序只做了Pin12, Pin13 LED閃爍來分辨我的 App1 跟 App2的程式碼 App1 程式碼 int ...
- ASP.NET MVC 4.0 学习2-留言板實現
新增專案實現留言板功能,瞭解MVC的運行機制 1,新增專案 2,添加數據庫文件message.mdf Ctrl+W,L 打開資料庫連接,添加存放留言的Atricle表 添加字段,後點擊&quo ...
- [Xamarin.Android] 結合Windows Azure與Google cloud message 來實現Push Notification (转帖)
這一篇要討論如何使用Xamarin.Android 整合GCM以及Windows Azure來實作Android手機上的推播通知服務. 這篇文章比較著重概念的部分,在開始讀這篇之前,也可以先參考一下X ...
- [實現DDD] 第10章 聚合(1)設計原則
聚合只是將一些實體(Entity)與值對象(Value Object)聚集起來的對象樹嗎?? 有些途徑可能使我們設計出不正確的聚合模型, 如:可能為了對象組合上的方便而將聚合設計的很大;也可能設計的聚 ...
- Jquery scrollTop animate 實現動態滾動到頁面頂部
這個方法之前都是用的錨點實現的,但是效果僵硬,動感不足! 之後參考了一些網站,發現都是用的js,於是自己想到用jquery 來做一個插件也來實現以下這個小功能. $.fn.backTop = func ...
- 【转】Visual Studio單元測試小應用-測執行時間
[转]Visual Studio單元測試小應用-測執行時間 Visual Studio的單元測試會記錄每一個測試的執行時間,如果有幾個Method要測效能,以前我會用Stopwatch,最近我都改用單 ...
- Neo4j中實現自定義中文全文索引
資料庫檢索效率時,一般首要優化途徑是從索引入手,然後根據需求再考慮更復雜的負載均衡.讀寫分離和分散式水平/垂直分庫/表等手段:索引通過資訊冗餘來提高檢索效率,其以空間換時間並會降低資料寫入的效率,因此 ...
随机推荐
- 【并行计算-CUDA开发】GPGPU OpenCL/CUDA 高性能编程的10大注意事项
GPGPU OpenCL/CUDA 高性能编程的10大注意事项 1.展开循环 如果提前知道了循环的次数,可以进行循环展开,这样省去了循环条件的比较次数.但是同时也不能使得kernel代码太大. 循环展 ...
- airflow原理
官网: http://airflow.apache.org/installation.html 原理: https://www.cnblogs.com/cord/p/9450910.html 原理介绍 ...
- (模板)hdoj5977 Garden of Eden(点分治)
题目链接:https://vjudge.net/problem/HDU-5977 题意:给一颗树,每个结点上有一个权值a[i],a[i]<=10,求有多少条路径满足这条路径上所有权值的结点都出现 ...
- SQL Server 数据备份存储过程
原文:SQL Server 数据备份存储过程 今天开园,分享一下我一直在使用的数据备份存储过程,欢迎转载!!! ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- Spring4学习回顾之路04—引用其他Bean,集合数据注入,内部Bean
引用其他Bean 组件应用程序的Bean经常需要相互协作以完成应用程序的功能,所以要求Bean能够相互访问,就必须在Bean配置文件中指定Bean的引用.在Bean的配置文件中可以用过<ref& ...
- PAT A1020 Tree Traversals(25)
题目描述 Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder ...
- springboot2.0结合freemarker生成静态化页面
目录 1. pom.xml配置 2. application.yml配置 3. 使用模板文件静态化 3.1 创建测试类,编写测试方法 3.2 使用模板字符串静态化 使用freemarker将页面生成h ...
- centos 秘钥登录
客户端系统:macOS 服务端系统:Centos7 另外:ip 为 172.25.11.182 用户名为 iamfine 1, 在客户端macOS上生成 rsa 对 ssh-keygen -t rsa ...
- Ansible-批量导入key(入门)
系统是centos7.5 python2.75 yum install -y ansible ssh-keygen -t rsa vim /etc/ansible/hosts 定义的一个hello组: ...
- 并不对劲的复健训练-bzoj5339:loj2578:p4593:[TJOI2018]教科书般的亵渎
题目大意 题目链接 题解 先将\(a\)排序. \(k\)看上去等于怪的血量连续段的个数,但是要注意当存在\(a_i+1=a_{i+1}\)时,虽然它们之间的连续段为空,但是还要算上:而当\(a_m= ...