【问题标题】:Process mutex on function处理函数上的互斥锁
【发布时间】:2016-05-09 09:59:29
【问题描述】:

如何锁定一个函数,使其阻止程序的其他实例执行它直到它完成?

我认为我需要某种系统互斥体和 WaitOne,但我不确定如何以稳健的方式将它们组合在一起。我在想……

public static void function()
{
    bool ok;

    using (Mutex mutex = new Mutex(true, "Set-IP Instance", out ok))
    {
        if(!ok)
        {                    
            mutex.WaitOne();
        }

        ...
    }
}  

【问题讨论】:

  • lock 声明还不够吗?在类中声明一个虚拟object pLock = new object(),并在函数的开头将所有内容包装在lock(pLock) { /* .. */ } 中。 (msdn.microsoft.com/en-us/library/c5kehkcz.aspx)。低级互斥体也应该可以工作。
  • @MaximilianGerhardt 否 - 锁只有在他有多个线程运行时才会起作用,而不是同一个程序执行多次时
  • 不,这不是为了防止同一程序的多个实例运行。这是为了防止多个实例同时运行相同的功能。上下文是我正在为一个硬件分配一个 IP 地址,并且用户可以同时插入多个,所以我需要确保我分配了唯一的地址。我想我应该在系统范围内锁定设置 IP 的功能。
  • “阻止程序的其他实例” 不够清楚。您是否需要阻止其他实例在同一桌面、同一用户帐户、同一台机器或全局上运行代码?

标签: c# windows mutex


【解决方案1】:

您正在寻找的行为可以通过此代码实现(简单版):

using(Mutex mutex = new Mutex(false, "GlobalMutexId"))
{
    mutex.WaitOne();
    //Do your thing
    mutex.ReleaseMutex();
}

或者,如果您更喜欢可重用的方法:

public class MutexFactory
{
    private string _name;

    public MutexFactory(string name)
    {
        _name = name;
    }

    public SingleUseMutex Lock()
    {
        return new SingleUseMutex(_name);
    }
}

public class SingleUseMutex : IDisposable
{
    private readonly Mutex _mutex;

    internal SingleUseMutex(string name)
    {
        _mutex = new Mutex(false, name);
        _mutex.WaitOne();
    }

    public void Dispose()
    {
        _mutex.ReleaseMutex();
        _mutex.Dispose();
    }
}

可以这样使用:

private void TestFunction()
{
    MutexFactory factory = new MutexFactory("YourMutexId");

    for (int i = 0; i < 100; i++)
    {
        // also works for new instances of your program of course
        new Thread(Interlocked).Start(factory);
    }
}

private void Interlocked(object obj)
{
    Guid guid = Guid.NewGuid();
    MutexFactory factory = obj as MutexFactory;
    using (factory.Lock())
    {
        Debug.WriteLine(guid.ToString("N") + " start");
        //Waste Time
        Thread.Sleep(50);
        Debug.WriteLine(guid.ToString("N") + " end");   
    }
}

【讨论】:

    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 2012-06-05
    • 1970-01-01
    • 2010-09-16
    • 2010-12-17
    相关资源
    最近更新 更多