c# - 替代监视器来检查记录是否存在,如果不存在则写入
问题描述
因此,我有一些 C# 代码,如下所示(出于问题的目的进行了简化,任何错误都来自我进行这些更改)。可以从多个线程或上下文以异步方式调用此代码。这样做的全部目的是确保如果记录已经存在,则使用它,如果不存在,则创建它。可能是也可能不是很好的设计,但这可以按预期工作。
var timeout = TimeSpan.FromMilliseconds(500);
bool lockTaken = false;
try
{
Monitor.TryEnter(m_lock, timeout, ref lockTaken); // m_lock declared statically above
if (lockTaken)
{
var myDBRecord = _DBContext.MyClass.SingleOrDefault(x => x.ForeignKeyId1 == ForeignKeyId1
&& x.ForeignKeyId2 == ForeignKeyId2);
if (myDBRecord == null)
{
myDBRecord = new MyClass
{
ForeignKeyId1 == ForeignKeyId1,
ForeignKeyId2 == ForeignKeyId2
// ...datapoints
};
_DBContext.MyClass.Add(myDBRecord);
_DBContext.SaveChanges();
}
}
else
{
throw new Exception("Can't get lock");
}
}
finally
{
if (lockTaken)
{
Monitor.Exit(m_lock);
}
}
如果有很多请求进来,就会出现问题,它可能会使监视器不堪重负,如果它必须等待太久就会超时。虽然锁定的超时时间当然可以更短,但解决此类问题的首选方法是什么(如果有的话)?任何试图查看是否需要输入监控代码的东西都需要成为该原子操作的一部分。
解决方案
我建议您完全摆脱监视器,而是处理重复键异常。无论如何,您必须处理尝试输入重复值的情况,为什么不直接这样做呢?
推荐阅读
- google-cloud-print - 如何在没有浏览器提示的情况下使用 aouth2 访问谷歌云打印?
- c++ - 尝试初始化结构向量时出现编译错误
- r - 将 20 GB csv 文件加载到 R 中的最佳方法是什么?
- python - 为 python3.7 Ubuntu 18.04 安装 pandas
- unity3d - 轻量级渲染管线弄乱了物体的纹理
- vue.js - Vue路由器链接按钮组件
- angular - Angular Protractor 如何使用 findElements(by.tagName) 获取 tr 中的所有 td
- angular - 使用 FileReader 正确读取文件
- vba - 项目时标数据 VBA 使用
- kotlin - Camel 组件 RabbitMQ 不耐用