C# 中是否有“尝试锁定,如果超时则跳过”操作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8546/
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-07-31 17:14:07  来源:igfitidea点击:

Is there a "try to lock, skip if timed out" operation in C#?

提问by gil

I need to try to lock on an object, and if its already locked just continue (after time out, or without it).

我需要尝试锁定一个对象,如果它已经锁定,则继续(超时后或没有它)。

The C# lock statement is blocking.

C# lock 语句正在阻塞。

采纳答案by Ed S.

I believe that you can use Monitor.TryEnter().

我相信你可以使用Monitor.TryEnter().

The lock statement just translates to a Monitor.Enter()call and a try catchblock.

lock 语句只是转换为Monitor.Enter()调用和try catch块。

回答by Derek Park

Ed's got the right function for you. Just don't forget to call Monitor.Exit(). You should use a try-finallyblock to guarantee proper cleanup.

Ed 为您提供了合适的功能。只是不要忘记打电话Monitor.Exit()。您应该使用try-finally块来保证正确的清理。

if (Monitor.TryEnter(someObject))
{
    try
    {
        // use object
    }
    finally
    {
        Monitor.Exit(someObject);
    }
}

回答by Will Dean

You'll probably find this out for yourself now that the others have pointed you in the right direction, but TryEnter can also take a timeout parameter.

您可能会自己发现这一点,因为其他人已经为您指明了正确的方向,但 TryEnter 也可以采用超时参数。

Jeff Richter's "CLR Via C#" is an excellent book on details of CLR innards if you're getting into more complicated stuff.

Jeff Richter 的“CLR Via C#”是一本关于 CLR 内部细节的优秀书籍,如果您正在研究更复杂的东西。

回答by cwills

I had the same problem, I ended up creating a class TryLockthat implements IDisposable and then uses the usingstatement to control the scope of the lock:

我遇到了同样的问题,我最终创建了一个TryLock实现 IDisposable的类,然后使用该using语句来控制锁的范围:

public class TryLock : IDisposable
{
    private object locked;

    public bool HasLock { get; private set; }

    public TryLock(object obj)
    {
        if (Monitor.TryEnter(obj))
        {
            HasLock = true;
            locked = obj;
        }
    }

    public void Dispose()
    {
        if (HasLock)
        {
            Monitor.Exit(locked);
            locked = null;
            HasLock = false;
        }
    }
}

And then use the following syntax to lock:

然后使用以下语法进行锁定:

var obj = new object();

using (var tryLock = new TryLock(obj))
{
    if (tryLock.HasLock)
    {
        Console.WriteLine("Lock acquired..");
    }
}

回答by David Burg

Consider using AutoResetEvent and its method WaitOne with a timeout input.

考虑使用 AutoResetEvent 及其带有超时输入的方法 WaitOne。

static AutoResetEvent autoEvent = new AutoResetEvent(true);
if(autoEvent.WaitOne(0))
{
    //start critical section
    Console.WriteLine("no other thread here, do your job");
    Thread.Sleep(5000);
    //end critical section
    autoEvent.Set();
}
else
{
    Console.WriteLine("A thread working already at this time.");
}

See https://msdn.microsoft.com/en-us/library/cc189907(v=vs.110).aspxhttps://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspxand https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx

请参阅https://msdn.microsoft.com/en-us/library/cc189907(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v =vs.110).aspxhttps://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx