C#中的方法锁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14977106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:38:15  来源:igfitidea点击:

Method lock in c#

c#.netmultithreadingthread-safety

提问by Emanuele Mazzoni

I have one class with these three methods. This class is used by many threads. I would like the Method1 to wait, if Method2 and/or Method3 are running in any threads. Any suggestions?

我有一个带有这三种方法的类。这个类被许多线程使用。如果 Method2 和/或 Method3 在任何线程中运行,我希望 Method1 等待。有什么建议?

public class Class1
{
    public static void Method1() 
    {
        Object lockThis = new Object();

        lock (lockThis)
        {
            //Body function
        }
    }

    public static void Method2() 
    {
         //Body function
    }

    public static void Method3() 
    {
         //Body function
    }
}

采纳答案by Paolo Tedesco

If I understood correctly, you need something like this:

如果我理解正确,你需要这样的东西:

static object lockMethod2 = new object();
static object lockMethod3 = new object();

public static void Method1() 
{
    lock (lockMethod2)
    lock (lockMethod3)
    {
        //Body function
    }
}

public static void Method2() 
{
    lock (lockMethod2)
    {
        //Body function
    }
}

public static void Method3() 
{
    lock (lockMethod3)
    {
        //Body function
    }
}

This allows method3 to execute if method2 is running and vice versa, while method1 must wait for both. Of course, method2 and 3 will not run while 1 is running.

这允许 method3 在 method2 正在运行时执行,反之亦然,而 method1 必须等待两者。当然,method2 和 3 不会在 1 运行时运行。

回答by Davin Tryon

If you are multi-threading then the lockhas to be accessible to all threads. Therefore, in this case, your locks needs to be static for the static methods to see it.

如果您是多线程,那么lock所有线程都必须可以访问它。因此,在这种情况下,您的锁需要是静态的,静态方法才能看到它。

Your current setup will make a new lock object for each thread. Therefore, providing now synchronization.

您当前的设置将为每个线程创建一个新的锁对象。因此,提供现在同步。

回答by Daniel Hilgarth

The current implementation of your lock is completely useless, because every thread will lock on a different object.
Locking is usually done with a readonly field that is initialized only once.
Like this, you can easily lock multiple methods:

您的锁的当前实现完全没有用,因为每个线程都将锁定不同的对象。
锁定通常使用只读字段完成,该字段仅初始化一次。
像这样,您可以轻松锁定多个方法:

public class Class1
{
    private static readonly object _syncRoot = new object();

    public static void Method1() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }

    public static void Method2() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }

    public static void Method3() 
    {
        lock (_syncRoot)
        {
            //Body function
        }
    }
}

回答by Coral Doe

I would suggest a ReaderWriterLockSlim(http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx)

我建议一个ReaderWriterLockSlimhttp://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

Similar to read operations, Method 2 and Method3 may occur in parallel, while Method1 (like a write operation) would need to wait for those to finish. It's not the regular read/write concurrency situation, but the logic is similar.

与读操作类似,方法 2 和方法 3 可以并行发生,而方法 1(如写操作)需要等待它们完成。这不是常规的读/写并发情况,但逻辑是相似的。

public class Class1
{
    private ReaderWriterLockSlim methodLock = new ReaderWriterLockSlim();
    public static void Method1() 
    {
        methodLock.EnterWriteLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitWriteLock();
        }
    }

    public static void Method2() 
    {
         methodLock.EnterReadLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitReadLock();
        }
    }

    public static void Method3() 
    {
         methodLock.EnterReadLock();
        try
        {
            //Body function
        }
        finally
        {
            methodLock.ExitReadLock();
        }
    }
}