我的情况如下:
我正在考虑使用系统范围的互斥锁的解决方案。然而,它在“出乎意料”的情况下并没有像它留下“废弃的”互斥体那样很好地存活下来。如果这是一个好方法,我可以问一下“忽略”被遗弃的互斥量是什么?
答案 0 :(得分:2)
一种方法是查询进程列表并计算当前活动的实例数。另一种方法,更多的是,广播UDP并计算响应的数量。我已将此模式用于与作业处理器相关的分布式方案。
HTH
非洲科尔比
答案 1 :(得分:0)
您可以使用共享内存段并在每次打开应用程序时递增计数,并在应用程序关闭时递减。一个更简单的方法可能是使用您在问题中提到的进程间信号量。
答案 2 :(得分:0)
当进程通过“意外”事件(例如任务管理器进程终止)终止时,它应抛出一个ThreadAbortException。你应该尝试将你的互斥锁包装在某种try / finally中,以便在线程中止时释放它。
我不是百分之百确定这是真的,但应该有某种方式来应对这种情况。
答案 3 :(得分:0)
扩展进程列表方法,将WMI.NET与 C#一起使用可能如下所示:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Management;
namespace WmiProc
{
class Program
{
static void Main(string[] args)
{
ManagementScope ms = new System.Management.ManagementScope(
@"\\myserver\root\cimv2");
var oq = new System.Management.ObjectQuery(
"SELECT * FROM Win32_Process where Name='myprocname'");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms, oq);
ManagementObjectCollection procsCollection = query1.Get();
Console.WriteLine("process count:{0}", procsCollection.Count);
}
}
}
编辑:开始时间会有一些分离,这样就不太可能同时运行太多进程。您必须测试环境中的特定行为。
也许您可以定期检查单独(长时间运行)流程中的流程计数,并根据某些标准(例如最新流程)终止多余流程。
答案 4 :(得分:0)
好吧,你可以使用已命名的Mutex实例。
对互斥锁使用个人命名方案,请求此名称并检查已创建此名称的互斥锁的结果。
如果您使用带增量元素的命名方案,您可以尝试使用增量元素升序的所有互斥锁名称,并计算这样的数量,创建了多少个互斥锁。
使用已发布的互斥锁处理需要一些改进,但这似乎微不足道。
class Program
{
private static Mutex mutex = null;
static void Main(string[] args)
{
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
int count = Program.CheckInstanceCount();
Console.WriteLine("This is instance {0} running.", count);
Console.Read();
}
static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
Program.mutex.ReleaseMutex();
Program.mutex.Close();
}
private static int CheckInstanceCount()
{
int result = 0;
bool created = false;
for (int i = 0; i < 50; i++)
{
/* try to create a mutex with this name,
* if it does exist, another instance
* of this program is running
*/
mutex = new Mutex(true, string.Concat(AppDomain.CurrentDomain.FriendlyName, i.ToString()), out created);
if (created)
{
// this instance is instance #i currently running
result = i;
break;
}
}
return result;
}
}
答案 5 :(得分:0)
我无法为上述答案添加评论,但通过阅读上述答案和评论,您似乎应该能够将互斥锁与流程实例检查结合起来。
// You can use any System wide mutual exclusion mechanism here
bool waitAndLockMutex();
void unlockMutex();
// returns the number of processes who use the specified command
int getProcessCount();
void main() {
try {
waitAndLockMutex();
if (getProcessCount() > MAX_ALLOWED)
return;
doUsualWork();
} finally {
unlockMutex();
}
}
请注意,上面的代码仅用于说明目的,并且可以使用.NET轻松编写声明函数调用的主体
编辑:
如果您不想计算感兴趣的过程,可以使用全局互斥。不确定.NET是否公开了。但要点是你可以获得所有的互斥体直到MAX,并且在这个过程中如果你得到一个尚未创建或被抛弃的Mutex,那么你继续让流程启动,否则退出说超过最大数量
void main() {
for (int i = 0; i < MAX; ++i) {
int status = TryToAcquireMutex("mutex" + i);
continue if (status == locked);
if (status == success || status == WAIT_ABANDONED) {
doUsusalWork();
}
}
}