[英]Does the C# Yield free a lock?
我有以下方法:
public static IEnumerable<Dictionary<string, object>> GetRowsIter
(this SqlCeResultSet resultSet)
{
// Make sure we don't multi thread the database.
lock (Database)
{
if (resultSet.HasRows)
{
resultSet.Read();
do
{
var resultList = new Dictionary<string, object>();
for (int i = 0; i < resultSet.FieldCount; i++)
{
var value = resultSet.GetValue(i);
resultList.Add(resultSet.GetName(i), value == DBNull.Value
? null : value);
}
yield return resultList;
} while (resultSet.Read());
}
yield break;
}
我刚刚添加了lock(Database)
来尝试摆脱一些尴尬的问题。 我很好奇, yield return
是否会释放Database
上的锁定,然后在下一次迭代时重新锁定? 或者Database
会在整个迭代期间保持锁定状态吗?
yield return
不会导致任何锁定被释放/解锁。 lock
语句将扩展为try / finally
块,并且迭代器不会对迭代器方法中的显式try / finally
进行任何不同的处理。
细节有点复杂,但finally
块在迭代器方法中运行的基本规则是
Dispose
时,将在暂停点的范围内运行finally
块 finally
触发finally
块时运行。 yield break
语句时, yield break
run的点范围内的finally
块将会运行 锁转换为try / finally(正常c#)
在Iterator块(又名yield)中,“finally”成为枚举器的IDisposable.Dispose()实现的一部分。 使用最后一个数据时,也会在内部调用此代码。
“foreach”会自动调用Dispose(),所以如果你使用“foreach”(或regualar LINQ等), 它将被解锁。
但是,如果调用者直接使用GetEnumerator()(非常罕见)并且不读取所有数据并且不调用Dispose(),则不会释放锁定。
我必须检查是否或获得终结者; 它可能会被GC释放,但我不会赌钱。
数据库对象将被锁定,直到迭代完成(或处理迭代器)。
这可能导致过多的锁定时间,我建议不要这样做。
锁定保持有效,直到您超出lock()的范围。 让步不会那样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.