c# - 监视器输入 ArgumentNullException
问题描述
我试图理解为什么我在方法上遇到ArgumentNull
异常。Monitor.Enter
调用代码仅使用NamedLocker
. 我正在使用锁来防止访问共享资源。正在处理的信号量是否会导致空引用异常?
System.ArgumentNullException: Value cannot be null.
at System.Threading.Monitor.Enter(Object obj)
at System.Threading.SemaphoreSlim.<WaitUntilCountOrTimeoutAsync>d__31.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
WaitAsync
在获得Semaphore
.
以下是我的代码:
public class NamedLocker
{
private static readonly Dictionary<string, SemaphoreSlim> _lockDict =
new Dictionary<string, SemaphoreSlim>();
private readonly Config config;
private static readonly object semLock = new object();
public NamedLocker(Config config)
{
this.config = config;
}
public async Task RunWithLock(string name, Func<Task> body)
{
try
{
_ = await GetOrCreateSemaphore(name)
.WaitAsync(TimeSpan.FromSeconds(5))
.ConfigureAwait(false);
await body().ConfigureAwait(false);
}
finally
{
_ = Task.Run(async () =>
{
await Task.Delay(this.config.LockDelayMilliseconds)
.ConfigureAwait(false);
RemoveLock(name);
});
}
}
public void RemoveLock(string key)
{
SemaphoreSlim outSemaphoreSlim;
lock (semLock)
{
if (_lockDict.TryGetValue(key, out outSemaphoreSlim))
{
_lockDict.Remove(key);
outSemaphoreSlim.Release();
outSemaphoreSlim.Dispose();
}
}
}
private SemaphoreSlim GetOrCreateSemaphore(string key)
{
SemaphoreSlim outSemaphoreSlim;
lock (semLock)
{
if (!_lockDict.TryGetValue(key, out outSemaphoreSlim))
{
outSemaphoreSlim = new SemaphoreSlim(1, 1);
_lockDict[key] = outSemaphoreSlim;
}
return outSemaphoreSlim;
}
}
}
这是我用来验证异常的测试:
[TestMethod]
public async Task PPP()
{
var namedLocker = new NamedLocker(new Config
{
LockDelayMilliseconds = 100
});
Func<Task> funcToRunInsideLock = async () => await Task.Delay(300);
var tasks = Enumerable.Range(0, 100).Select(
i => namedLocker.RunWithLock((i % 2).ToString(), funcToRunInsideLock));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
编辑:删除Dispose()
infinally
块(inside RemoveLock
)使其在没有空异常的情况下工作。我不明白为什么会这样。
解决方案
推荐阅读
- amazon-web-services - 是否有可能达到 Lambda 调用限制(10000)而不达到其并发限制(1000)?
- java - RecyclerView 的 SearchView 不起作用
- html - 我的网站无法显示 firebase 实时数据库数据
- python - python延迟加载模式使用循环中的最后一个值
- css - 如何将卡片垂直排列成两列
- react-native - 如何在wix Navigation中将道具传回父组件
- php - Laravel msql配置%db_name%缓存问题
- mql4 - 如何分离 2 Close[1]?
- python - 对隐式列名的操作
- file-manager - DotNetNuke 中的文件管理器模块