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
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 catch
block.
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-finally
block 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 TryLock
that implements IDisposable and then uses the using
statement 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).aspx和 https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx