使用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();
...
时间: 2024-10-08 14:02:01

使用Mutex實現單一程式執行個體的注意事項(转)的相关文章

Spring框架整合mybais框架-注入映射器實現

通過上面一個案例,我們能夠看到,每次在執行具體的某個方法的時候,我們都會創建一個映射器,這是非常麻煩的,這就是我們所看到的UserMapperImpl.java,那麽我們能不能將他省略掉了,將創建映射器的方法交給Spring的ioc容器進行管理,答案是肯定的 aplicationContext.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.s

linux下c++實現簡單的生產者消費者隊列模式

引言 生產者消費者是一個經典的模式 利用生產者,消費者和緩衝區降低了生產者和消費者之間的的耦合度 便於對生產者和消費者的修改 下面記錄的是一個經典的單一生產者多消費者的模式 設計思路 以隊列做為緩衝區,實現產品的FIFO 生產者調用緩衝區的push函數,將產品加入緩衝區 消費者調用緩衝區的pop函數,將產品從緩衝區取出 因為生產者與消費者分屬於不同的線程,所以要設置鎖 類的聲明 class CacheQueue { private: /** * @brief 緩衝隊列 */ queue<int>

ASP.NET MVC 4.0 学习2-留言板實現

新增專案實現留言板功能,瞭解MVC的運行機制 1,新增專案   2,添加數據庫文件message.mdf   Ctrl+W,L 打開資料庫連接,添加存放留言的Atricle表 添加字段,後點擊"更新"後看到新增的Atricle表(Content 應該設置為text) 3,添加ADO.NET實體數據模型 (MVC通過實體數據模型對數據庫中的數據進行增删改查)              ADO.NET實體數據模型添加完成. 4,建立Service 我們把對Model中message.mdf

[DE0-NANO] HC-05藍芽模組實現與測試(二)

篇是接續  [DE0-NANO] HC-05藍芽模組實現與測試(一) 本篇主要功能是將RFS板與電腦連接.硬體程式與上一篇相同. 在NIOS軟體部分,我新增了一個SLAVE模式,把RFS板上的HC05設為被動模式(SLAVE). 操作步驟 -------------------------------------------------------------------------- 1. 下載 DE0_Nano.sof 2.斷掉RFS板子電源,按下BT_KEY後在接上RFS板子電源. (此時

那些年我們未實現的夢

昨天晚飯之後和大學同學在西門町紅樓後面的酒吧聊了很多,聊了過去,現在,當然也不斷地在弄清我們的未來. “清華北大” 這是我的第一個夢想吧,可能大多數中國的學生的夢想,但是能去的人才有幾個呢.特別是在小城市,每年也就三四個考上清華和北大的.大我兩歲的表哥還是我們市歷史上第一個報送到清華的學生,而下一個這麼多年過去也一直沒有.我不算是很努力的學生,但是覺得自己有點小聰明,也沒有像別人題海戰術,基本上就是把老師上課的內容搞明白,時常溫故而知新.從高一開始的年級400多名,經過一年努力,逐步穩定在二十名

【转】Visual Studio單元測試小應用-測執行時間

[转]Visual Studio單元測試小應用-測執行時間 Visual Studio的單元測試會記錄每一個測試的執行時間,如果有幾個Method要測效能,以前我會用Stopwatch,最近我都改用單元測試來測,快又簡單. Visual Studio的單元測試會記錄每一個測試的執行時間,如果有幾個Method要測效能,以前我會用Stopwatch,最近我都改用單元測試來測,快又簡單. 範例程式:有人說Catch不加Expection,因為不用匹配會比較快,我不相信,就來測測看. { for (i

用web報表工具實現同期比

由finereport報表軟體製作 同期比,指的是一個與時間相關的運算. 上圖報表顯示的就是在同一年內每一個月份與上一個月份的比值. 下面我們來看一下實現上述報表的過程,工具FineReport報表 1.連接資料庫frDemo 2.設計報表 2.1新建報表 2.2表樣設計 按照下圖設計好報表的基本框架 2.3新建一數據集名為ds1 SQL語句:訂單.訂購日期,訂單明細.單價,訂單明細.數量訂單.訂購日期 訂購年份訂單.訂購日期訂購月份,訂單明細.數量*訂單明細.單價訂購金額訂單,訂單明細訂單.訂

JAVA中實現鏈表--LinkedList的使用

import java.util.LinkedList;import java.util.Vector; /** * Java中的鏈表,SUN公司已經為我們做好了,我們只需要簡單的使用就可以了 * 當沒有要求的時候,就可以不用自己去實現. * 如果確實有要求要自己實現,那么也自己實現也是一樣的道理,只需要像 * LinkedList中一樣,實現向個接口方法,同樣可以做到. * 這里是一個簡單的例子,如果相參看自己實現的鏈接,可以去這里: * http://blog.csdn.net/fengli

css 實現微信聊天類似的氣泡

要實現這樣的效果 代碼如下: --------------------------------------- <style> .test{width:300px; padding:30px 20px; margin-left:60px; margin-top:100px; background:#beceeb; position:relative;} .test span{width:0; height:0; font-size:0; overflow:hidden; position:abs