[英]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.