基于带计数器的命名互斥锁的C#线程安全锁
我需要在C#中编写一个dll,以用作系统范围(windows 10)的存储库。我需要有其他应用程序的唯一命名实例,应该有可能获得实例的当前计数。它应该是线程安全的,系统范围(跨进程),不创建额外的数据库/文件,并且只使用系统组件(没有外部包)。也应该有可能提供高百分比的测试覆盖率(100就完美了)。最后一个要求是发布实例,即使开发人员在程序中忘记了它 经过研究,我的想法是使用命名互斥体来确保它是跨进程的,并在系统中维护实例的唯一名称。完成了这些之后,我使用了信号量类来获得适当的跨进程计数器。要发布实例,有IDisposable接口和finallizer。附加课程似乎有效,但我这边有两个问题基于带计数器的命名互斥锁的C#线程安全锁,c#,multithreading,mutex,semaphore,named,C#,Multithreading,Mutex,Semaphore,Named,我需要在C#中编写一个dll,以用作系统范围(windows 10)的存储库。我需要有其他应用程序的唯一命名实例,应该有可能获得实例的当前计数。它应该是线程安全的,系统范围(跨进程),不创建额外的数据库/文件,并且只使用系统组件(没有外部包)。也应该有可能提供高百分比的测试覆盖率(100就完美了)。最后一个要求是发布实例,即使开发人员在程序中忘记了它 经过研究,我的想法是使用命名互斥体来确保它是跨进程的,并在系统中维护实例的唯一名称。完成了这些之后,我使用了信号量类来获得适当的跨进程计数器。要发
class GlobalLocker : IGlobalLocker, IDisposable
{
private static readonly string SEMAPHORE_NAME = "Global\\GlobalLockerSemaphore";
private static Semaphore _semaphore;
private static List<Mutex> _mutexes;
public GlobalLocker()
{
_mutexes = new List<Mutex>();
if (Semaphore.TryOpenExisting(SEMAPHORE_NAME, out _semaphore))
{
}
else
{
_semaphore = new Semaphore(0, int.MaxValue, SEMAPHORE_NAME);
}
}
~GlobalLocker()
{
Dispose();
}
public void Dispose()
{
WriteLine("Void dispose method started");
_mutexes.ForEach(x =>
{
x.ReleaseMutex();
x.Dispose();
x.Close();
_semaphore.WaitOne(0);
});
_mutexes = null;
WriteLine("Void dispose method finished");
}
public bool TryLock(string lockId)
{
bool mutexWasCreated;
var mutex = new Mutex(true, "Global\\" + lockId, out mutexWasCreated);
if (mutexWasCreated)
{
_semaphore.Release();
_mutexes.Add(mutex);
return true;
}
return false;
}
public int GetLocksCount()
{
_semaphore.WaitOne(0);
return _semaphore.Release();
}
public static void WriteLine(string x)
{
Console.WriteLine($"{DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")}: { x}");
}
}
类GlobalLocker:iglobalocker,IDisposable
{
私有静态只读字符串信号量\u NAME=“Global\\globallockeremaphore”;
专用静态信号量\u信号量;
私有静态列表_互斥体;
公共GlobalLocker()
{
_互斥量=新列表();
if(Semaphore.TryOpenExisting(Semaphore\u NAME,out\u Semaphore))
{
}
其他的
{
_信号量=新信号量(0,int.MaxValue,信号量\名称);
}
}
~GlobalLocker()
{
处置();
}
公共空间处置()
{
WriteLine(“已启动无效处置方法”);
_mutex.ForEach(x=>
{
x、 释放互斥锁();
x、 处置();
x、 Close();
_信号量WaitOne(0);
});
_互斥量=null;
WriteLine(“无效处置方法完成”);
}
公共布尔锁(字符串锁ID)
{
创建布尔互斥;
var mutex=新的互斥体(true,“Global\\\”+lockId,out mutexwasweated);
如果(mutexWasCreated)
{
_semaphore.Release();
_添加(互斥);
返回true;
}
返回false;
}
public int getLockScont()
{
_信号量WaitOne(0);
return_semaphore.Release();
}
公共静态无效写线(字符串x)
{
Console.WriteLine($”{DateTime.Now.ToString(“MM/dd/yyyy HH:MM:ss”)}:{x});
}
}
有人能向我解释一下,为什么退出了第一个互斥锁却没有被释放?是什么导致了这种差异,即在退出第二个实例时,它们都被释放了?初始所有权意味着如果它是真的,并且
mutexwastcreated
out变量也返回了真-那么调用者现在拥有互斥体,而不显式调用WaitOne
。至于第二部分,如果您包含复制错误的测试代码,则会更容易。错误不是由于测试代码而产生的,而是手动进行的冒烟测试。