【发布时间】:2013-01-23 20:11:07
【问题描述】:
我正在尝试使用命名系统互斥锁的方法来同步两个进程-
- 一个 c# windows 服务
- 桌面 C# 应用程序
创建互斥体时,未创建互斥体的进程似乎没有检测到现有的互斥体。下面更详细的:
Windows 服务负责创建互斥体(无前缀-全局/本地等。只是一个普通的命名系统互斥体)如下:
Mutex myMutex= null;
try
{
myMutex= Mutex.OpenExisting(myMutexName);
}
catch (WaitHandleCannotBeOpenedException x)
{
//doesn't exist.
try
{
this.GetLogger().Info("Create Mutex");
bool createdNew = false;
new Mutex(false, myMutexName, out createdNew);
if (!createdNew) throw new Exception("Unable to create Mutex");
}
catch (Exception ex)
{
this.Stop();
}
}
catch (Exception x)
{
this.Stop();
}
finally
{
if (myMutex!= null)
{
try
{
myMutex.ReleaseMutex();
}
catch(Exception x)
{
this.GetLogger().Warn("Unable to release mutex");
}
}
}
我在 onStart() 中有这个。此外,我在此互斥体上同步服务的其他地方。
现在,我在应用程序中这样使用它:
Mutex myMutex= null;
try
{
myMutex= Mutex.OpenExisting(this.myMutexName);
myMutex.WaitOne();
//do required stuff
}
catch (WaitHandleCannotBeOpenedException wcbox)
{
//doesn't exist yet. service not running??
this.GetLogger().Error("Background Service is not Running");
shutdownApp();
}
finally
{
if (myMutex!= null)
{
try
{
myMutex.ReleaseMutex();
}
catch (Exception x)
{
}
}
}
我的问题:
在服务运行时,应用程序抛出 WaitHandleCannotBeOpenedException,这意味着它看不到存在的互斥体(我使用工具“WinObj”验证了这一点,互斥体存在于“BaseNamedObjects”下,类型为“Mutant”)。为什么?我在登录时使用同一帐户运行服务。即使没有,这也不应该是问题,因为命名互斥锁是操作系统范围的对象,对吗?
我不清楚互斥锁何时会被销毁。目前,我看到当我启动服务时创建了互斥锁,当我停止服务时,我看到互斥锁不再存在(WinObj)。这是否意味着当没有人在等待互斥锁并且创建者进程结束时,它会被垃圾回收?
一般来说,命名系统互斥体的生命周期是多少。具体什么时候死?
【问题讨论】:
-
你试过`全局`前缀吗?
-
@AntonKovalenko - 我不想尝试它,因为它与终端服务等有关。我想坚持使用非前缀名称,直到有人告诉我在做什么可能行不通。处理终端服务用户场景不是我的要求
-
问题是,服务(在现代 Windows 上)默认为全局命名空间,而正常登录会话中的应用程序默认为本地。因此,您正在做的事情可能行不通。
-
@Brian 命名空间并非特定于终端服务。您的服务和应用程序在不同的会话中运行。这就是问题所在。