【发布时间】:2011-06-04 05:45:04
【问题描述】:
我有以下方法:
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 会在整个迭代期间保持锁定状态吗?
【问题讨论】:
-
参见csharpindepth.com/Articles/Chapter6/…中的“和
finally…” -
这可能是一个非常糟糕的主意。当您可以在获得锁和释放锁之间运行任意代码时,很难控制锁的顺序。这只是要求死锁。
-
@Eric Lippert - 我对多线程编码不太熟悉。 (尽管我越做越好。)我现在知道 lock 语句的“魔力”实际上只是一个
try finally块,并且yield在它处于屈服状态时将事物保持在范围内。考虑到这一点,将锁移动到仅围绕for循环。这给了我对我需要的 SQL Server CE 访问的限制,而在“关闭”迭代时间期间不锁定。 (至少我希望如此!) -
补充 Eric 的评论:获取锁的代码甚至可能在与(试图)释放它的代码不同的线程中运行。