微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于带有计数器的

如何解决基于带有计数器的

我需要在C#中编写一个dll,以用作系统范围的(Windows 10)储物柜。我需要具有其他应用程序的唯一命名实例,并且应该有可能获取实例的当前数量。它应该是线程安全的,系统范围的(跨进程),不创建其他数据库/文件并且仅使用系统组件(不使用外部程序包)。还应该有可能提供较高百分比的测试覆盖率(100个为最佳)。最后的要求是释放实例,即使开发人员在程序中忘记了实例。

经过研究,我的想法是使用命名的互斥锁来确保它是跨进程的,并在系统中维护实例的唯一名称。完成后,我使用了Semaphore类来获取适当的跨进程计数器。要释放实例,有Idisposable接口和终结器。上课似乎可行,但是我身边有两个问题。

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}");
        }
    }
  1. 根据MSDocs

使用布尔值初始化Mutex类的新实例,该布尔值指示调用线程是否应具有互斥量的初始所有权,作为互斥量名称的字符串以及当方法返回时的布尔值,指示是否向调用线程授予了互斥锁的初始所有权。

线程是否具有初始所有权,意味着它是完全线程安全的,并且没有其他线程可以影响当前实例的互斥体?

  1. 我已经进行了一些冒烟测试,并且存在一种错误/问题。有一种情况:打开了3个控制台应用程序,每个应用程序都有一个GlobalLocker类的实例,在第一个实例中,锁定的互斥锁的锁ID为“ one”。那时,在第三个实例中,计数器返回1,而我无法使用lockId“ one”锁定互斥体-一切都完美。在第二个实例中,我用lockId“ two”锁定了互斥锁,第三个实例中的计数器返回了2,仍然可以。第一个实例以代码完成并带有消息的形式退出,表明dispose方法也成功。当时的第三个实例返回了1,但是在第二个实例中,我无法用lockId“ one”锁定互斥锁,该锁应该在那时可用。在退出第二实例并处理资源后,第三实例的计数器返回0,我可以将两个lockIds都锁定为“一个”和“两个”。

有人可以向我解释一下,为什么没有释放第一个互斥体的第一个实例?造成差异的原因是,两个出口都被释放了?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。