コード スニペットを次に示します。
private static ApplicationParameter TryGet(MyDataContext ctxt, string parameterName) {
return ctxt.GetTable<ApplicationParameter>().Where(p => p.Name.ToLower() == parameterName.ToLower()).SingleOrDefault();
}
private static Dictionary<string, string> _cache = new Dictionary<string, string>();
public static string GetValue(string parameterName) {
if (!_cache.ContainsKey(parameterName))
using (var ctxt = new MyDataContext()) {
var ap = TryGet(ctxt, parameterName);
if (ap != null)
_cache[parameterName] = ap.Value;
else
_cache[parameterName] = null;
}
return _cache[parameterName];
}
ほとんどの場合、このコードは問題なく動作します。ただし、負荷テストでは、悪名高い「Open DataReader」エラーがTryGet()
メソッドで発生することがあり、コール スタックはそれが通過したことを示していますGetValue()
。
私の人生では、これがどのように可能かわかりません。using
の呼び出しの周りにブロックを使用していることは明らかTryGet
で、 の新しいインスタンスがありMyDataContext
、クエリは 1 つしかありません。DataReader
では、どうしてすでにそこにオープンがある可能性があるのでしょうか?
MyDataContext
(明らかに から継承する)のすべてのインスタンス間に何らかの共有接続がDataContext
あり、2 つのスレッドが同時にConnection
プロパティを使用しようとすると、2 つの異なるデータ コンテキストであっても、どういうわけか両方とも同じにアクセスしているDataReader
場合を除きます。
これは本当でしょうか?他にどんな説明があるでしょうか?
編集:OnCreated
のメソッドにロガーを配置し、データ コンテキストとそのプロパティの両方MyDataContext
の値をログに記録しました。そこには重複がないので、同じオブジェクトを共有していないと思います-少なくとも、通常の使用法では. ロギングをインストールして以来、「open datareader」エラーは発生していません。しかし、同じ接続オブジェクトを使用していなくても、何らかの理由で DB への同じ接続を共有しているのではないでしょうか?GetHashCode
Connection