gpt4 book ai didi

c# - 链式锁?

转载 作者:行者123 更新时间:2023-11-30 16:02:07 26 4
gpt4 key购买 nike

尝试回答以下问题时 question ,我写了这段代码:

using static MyNameSpace.Locker; //So that we don't need to specify the static class name before each call.
public class MainClass
{
public MainMethod()
{
Lock(new object()).Lock(new object()).RunAction(() => Console.WriteLine("Finished"));
}
}


public static class Locker
{
public static async Task<List<object>> Lock(object toLock, int timeout = -1)
{
await Task.Run(() => TryEnter(toLock, timeout));
return new List<object>() { toLock };
}

public static async Task<List<object>> Lock(
this Task<List<object>> lockedChain,
object toLock,
int timeout = -1)
{
await Task.Run(() => TryEnter(toLock, timeout));
await lockedChain;
lockedChain.Result.Add(toLock)
return lockedChain.Result;
}

public static async void RunAction(this Task<List<object>> lockChain, Action toRun)
{
await lockChain;
try
{
toRun.Invoke();
}
finally
{
foreach (var chainMember in lockChain.Result)
{
Monitor.Exit(chainMember);
}
}
}

private static void TryEnter(object toLock, int timeout = -1)
{
var success = false;
if (timeout > 0)
{
success = Monitor.TryEnter(toLock, timeout);
}
else
{
success = Monitor.TryEnter(toLock);
}

if (!success)
{
throw new TimeoutException();
}
}
}

但正如某些用户正确评论的那样,这行不通的原因非常简单:由于这些方法是异步的,它们可能不会在同一线程上运行,因此在尝试释放 Monitor 时会抛出异常。

如何确保监视器的 EnterExit 方法在同一线程上运行?

最佳答案

与其将锁定操作强制到几乎不可能的同一个线程,不如使用非线程仿射的锁:SemaphoreSlim。它还具有 native 异步支持(与阻塞相反)。

在您链接到的原始问题中,我会选择 this answer反而。看起来比包含大量人为复杂性的链式解决方案更清洁。代码质量与所使用的特定调用语法无关。仅仅通过将事物放入句法链中并不能降低复杂性。

特别是链解决方案只是一种复杂的表达方式 Lock(new [] { lock1, lock2 }, () => ...); 我认为。所有的链都会建立一个列表。 using 使这更简单,因为它取消了 lambda。 Lambda 的可组合性较差,因为您不能像从 using 中那样从 lambda 返回。我认为你应该瞄准这个:

using (MultiLock(new [] { lock1, lock2 }, timeout)) {
//...
}

关于c# - 链式锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37963930/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com