GC吃了我的互斥体吗?为什么Mutex需要是静态的? [英] Did GC eat my mutex? Why did Mutex need to be static?

查看:98
本文介绍了GC吃了我的互斥体吗?为什么Mutex需要是静态的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用互斥锁禁止启动第二个应用程序实例。这个

在发布版本中不起作用,直到我把它作为我的

MainForm类的静态成员。


在调试中构建,第一个实例获得所有权,第二个没有并且

终止。在发布版本中,第二个实例*也获得了

所有权。我固定了它通过使互斥锁成为我的

MainForm类的静态成员。


垃圾收集器是否因为没有引用而使用我的互斥锁
$在调用Application.Run之后再次b $ b?


我无法在一个新的简单WinForm项目中重现这个问题;我尝试了

使所有项目设置相同。这里的代码没有

在发布版本中工作。


[STAThread]

static void Main()

{

试试

{

bool firstInstance = false;

string safeName = Application.UserAppDataPath.Replace(@" \"," _");

Mutex mutex = new Mutex(true,safeName,out firstInstance);

if(false == firstInstance)

{

return;

}

Application.Run(new FrmMain ());

}

catch(Exception ex)

{

Err.Show(ex," ;在FrmMain中遇到意外的异常);

}

}

I use a mutex to disallow starting a second application instance. This
did not work in a release build until I made it static member of my
MainForm class.

In a debug build, first instance got ownership, second did not and
terminated. In a release build, the second instance *also* got
ownership. I "fixed" it by making the mutex a static member of my
MainForm class.

Did the garbage collector eat my mutex because it is not referenced
again after Application.Run is called?

I could not reproduce this on a new simple WinForm project; I tried
making all the project setting the same. Here''s the code that did not
work in release build.

[STAThread]
static void Main()
{
try
{
bool firstInstance = false;
string safeName = Application.UserAppDataPath.Replace(@"\","_");
Mutex mutex = new Mutex(true, safeName, out firstInstance);
if(false == firstInstance)
{
return;
}
Application.Run(new FrmMain());
}
catch(Exception ex)
{
Err.Show(ex, "Caught an unexpected exception in FrmMain");
}
}

推荐答案

Ed Sutton< S _ ************* @ nomadics.com>写道:
Ed Sutton <S_*************@nomadics.com> wrote:
垃圾收集器是否因为在调用Application.Run后没有引用
而使用我的互斥锁?


是的 - 这样做很自由。

我无法在一个简单的新WinForm项目中重现这个问题。我试着让所有的项目设置都一样。这是在发布版本中没有工作的代码。

[STAThread]
static void Main()
{
尝试
{
bool firstInstance = false;
字符串safeName = Application.UserAppDataPath.Replace(@" \"," _");
Mutex互斥锁=新互斥锁(true ,safeName,out firstInstance);
if(false == firstInstance)
{
返回;
}
Application.Run(new FrmMain());
}
catch(Exception ex)
{
Err.Show(例如,在FrmMain中捕捉到意外的异常);
}
}
Did the garbage collector eat my mutex because it is not referenced
again after Application.Run is called?
Yes - it''s quite at liberty to do so.
I could not reproduce this on a new simple WinForm project; I tried
making all the project setting the same. Here''s the code that did not
work in release build.

[STAThread]
static void Main()
{
try
{
bool firstInstance = false;
string safeName = Application.UserAppDataPath.Replace(@"\","_");
Mutex mutex = new Mutex(true, safeName, out firstInstance);
if(false == firstInstance)
{
return;
}
Application.Run(new FrmMain());
}
catch(Exception ex)
{
Err.Show(ex, "Caught an unexpected exception in FrmMain");
}
}




放一个GC.KeepAlive(互斥锁);在你的试块结束时,所有人都应该好了。


-

Jon Skeet - < sk ***@pobox.com>
http://www.pobox.com / ~siget

如果回复群组,请不要给我发邮件



Put a GC.KeepAlive(mutex); at the end of your try block, and all should
be well.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


我刚发现它在发布中有效如果我在Application.Run()之后添加一个mutex.Close()

,则构建。


看来我需要了解GC的工作原理。


-Ed

Ed Sutton写道:
I just discovered it works in a release build if I add a mutex.Close()
after Application.Run().

It appears I need to learn about how the GC works.

-Ed
Ed Sutton wrote:
我使用互斥锁禁止启动第二个应用程序实例。这个
在我将它作为我的
MainForm类的静态成员之前在发布版本中不起作用。

在调试版本中,第一个实例获得所有权,第二个实例没有和<终止了。在发布版本中,第二个实例*也*获得了所有权。我固定了它通过使互斥锁成为我的MainForm类的静态成员。

垃圾收集器是否因为在调用Application.Run后没有引用
而使用我的互斥锁?

我无法在一个新的简单WinForm项目中重现这个问题;我试着让所有的项目设置都一样。这是在发布版本中没有工作的代码。

[STAThread]
static void Main()
{
尝试
{
bool firstInstance = false;
字符串safeName = Application.UserAppDataPath.Replace(@" \"," _");
Mutex互斥锁=新互斥锁(true ,safeName,out firstInstance);
if(false == firstInstance)
{
返回;
}
Application.Run(new FrmMain());
}
catch(Exception ex)
{
Err.Show(例如,在FrmMain中捕捉到意外的异常);
}
}
I use a mutex to disallow starting a second application instance. This
did not work in a release build until I made it static member of my
MainForm class.

In a debug build, first instance got ownership, second did not and
terminated. In a release build, the second instance *also* got
ownership. I "fixed" it by making the mutex a static member of my
MainForm class.

Did the garbage collector eat my mutex because it is not referenced
again after Application.Run is called?

I could not reproduce this on a new simple WinForm project; I tried
making all the project setting the same. Here''s the code that did not
work in release build.

[STAThread]
static void Main()
{
try
{
bool firstInstance = false;
string safeName = Application.UserAppDataPath.Replace(@"\","_");
Mutex mutex = new Mutex(true, safeName, out firstInstance);
if(false == firstInstance)
{
return;
}
Application.Run(new FrmMain());
}
catch(Exception ex)
{
Err.Show(ex, "Caught an unexpected exception in FrmMain");
}
}



Ed Sutton< S _ ************* @ nomadics.com>写道:
Ed Sutton <S_*************@nomadics.com> wrote:
我刚发现它在发布版本中工作,如果我在Application.Run()之后添加一个mutex.Close()


看来我需要了解GC的工作原理。
I just discovered it works in a release build if I add a mutex.Close()
after Application.Run().

It appears I need to learn about how the GC works.




基本上GC可以告诉mutex变量不再使用

之后'已创建,所以它不再被视为直播。


-

Jon Skeet - < sk *** @ pobox.com>
http://www.pobox.com/~skeet

如果回复小组,请不要给我发邮件



Basically the GC can tell that the mutex variable isn''t used again
after it''s created, so it''s no longer considered "live".

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


这篇关于GC吃了我的互斥体吗?为什么Mutex需要是静态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆