惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 【当耐特】
T
Tailwind CSS Blog
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
P
Proofpoint News Feed
博客园_首页
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
AI
AI
云风的 BLOG
云风的 BLOG
有赞技术团队
有赞技术团队
SecWiki News
SecWiki News
Google Online Security Blog
Google Online Security Blog
W
WeLiveSecurity
V
V2EX
K
Kaspersky official blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Blog — PlanetScale
Blog — PlanetScale
V
Vulnerabilities – Threatpost
Recent Announcements
Recent Announcements
aimingoo的专栏
aimingoo的专栏
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
博客园 - 司徒正美
V
Visual Studio Blog
L
Lohrmann on Cybersecurity
C
Cisco Blogs
A
About on SuperTechFans
N
News | PayPal Newsroom
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
罗磊的独立博客
A
Arctic Wolf
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Secure Thoughts
AWS News Blog
AWS News Blog
TaoSecurity Blog
TaoSecurity Blog
T
Tenable Blog
Engineering at Meta
Engineering at Meta

博客园 - 熵星尘

苦逼的程序员都是这么玩游戏的(微信:天天连萌) 关于ASP.NET动态加载控件的几点实用总结 记录代码运行耗时的写法 关于Linq to DataTable not in的写法 DevExpress AspxGridView数据绑定 发现一个Membership的bug 无法将类型为“Oracle.DataAccess.Types.OracleString”的对象强制转换为类型“System.String”。 asp.net页面中文件下载的2种方式 - 熵星尘 - 博客园 gridview 的添加删除等技巧 全部按名称取值 【部分转】innerText 跟 innerHTML区别 asp.net验证组件membership登录失败的问题 母板页中的引用的图片,JS,css等路径问题 - 熵星尘 - 博客园 如何获取GridView的EmptyDataTemplate中的控件 VS2008 如何在WinForm中显示flash - 熵星尘 - 博客园 【原创】从图像转换到byte[]数组的几种方法 除夕晚的一帖:如何为repeater内部控件设置javascript,如何取得它们的客户端ID。 回发或回调参数无效。 问题的解决和思考 - 熵星尘 - 博客园 【作品发布】正式发布Tuff的神奇小软盘1.2 【作品发布】QQ2008远程自助 1.5.1.1
Mutex实现单实例,你真的搞懂了吗?来看看吧。
熵星尘 · 2009-03-17 · via 博客园 - 熵星尘

通常需要winform只运行一个实例的话,我们用这样一个方法
修改Program.cs

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;namespace StudentGUI
{
    
static class Program
    {
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>
        [STAThread]
        
static void Main()
        {
            
bool IsRunning;
            Mutex mutex 
= new Mutex(true"StudentGUI"out IsRunning);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(

false);
            
if (IsRunning)
            {
                Application.Run(
new Form1());
            }
        }
    }
}

然而,同样的代码在我的一个工程里做debug编译和release编译的结果就是不同。
debug无论如何都是能正确的在第二个实例不执行Application.Run(new Form1()); 也就是IsRunning是false
release版本如果你回去做个空的winform写上这样的代码保证你可以实现单实例效果, 但是!!我的工程里面release的IsRunning总是true
也就是没有效果了。。。

我花了很多时间去精简我的工程,到最后,我的工程只有了几个空的panel和一个form1的背景,仍然在release没有效果。
这时候,我任意删掉一个panel,甚至换一个form1的backgroundimage都会正常起来。

我疑惑的是什么情况下会使的这个IsRunning在release编译下总为Ture。
当然我给客户一个debug编译是没有任何问题的,但是问题总是困扰我。

我在CSDN上讨论后,有了这样的答案。

Debug版延长了mutex的生命(以便被调试),而Release版则任由mutex被垃圾回收。
如果前一个实例中的mutex被回收了,后一个实例当然侦测不到已经释放的mutex了。

解决方法,把mutex写为静态成员:

static class Program
{
    
static Mutex mutex;                      //<----

    [STAThread]
    
static void Main()
    {
        
bool IsRunning;
        mutex 
= new Mutex(true"StudentGUI"out IsRunning);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(

false);
        
if (!IsRunning)
        {
            Application.Run(
new Form1());
        }
    }
}

或在程序末尾再次使用它,避免被垃圾回收:

static void Main()
    {
        
bool IsRunning;
        Mutex mutex 
= new Mutex(true"StudentGUI"out IsRunning);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(

false);
        
if (!IsRunning)
        {
            Application.Run(
new Form1());
        }

        (mutex 

as IDisposable).Dispose();      //<---
    }

当然,还可以这样阻止被回收:

[STAThread] 
        
static void Main() 
        { 
            
bool IsRunning; 
            Mutex mutex 
= new Mutex(true"StudentGUI"out IsRunning); 
          
            Application.EnableVisualStyles(); 
            Application.SetCompatibleTextRenderingDefault(
false); if (IsRunning) 
            { 
                Application.Run(
new Form1()); 
                GC.SuppressFinalize(mutex); 
            } 
        } 

这个问题其实挺难,我和一个朋友甚至去看Mutex的源代码;

这个问题其实也挺容易,release和debug的区别并不多,所以问题应该很容易找到;

因为涉及多线程,还考虑过多线程的问题,应该说是Framework学的不够好,再去啃啃CLR Via那本书吧。。。