私たちは一度完了した確認メールを送信する登録型システムを持っています。システムには数分で約3000件の登録があり、バグに気付きました。ユーザーBが登録してから数ミリ秒後にユーザーAが登録すると、ユーザーAはユーザーBの詳細を電子メールで取得します。私たちはこの問題を解決することができました。私はこのコードを、キャッシュから電子メールテンプレートを取得し、プレースホルダー上の文字列置換を行うコードに絞り込みました。テキスト文字列を置き換えるときの奇妙なC#のバグ
private string ProcessEmailBody(MyRegistrationModel registration)
{
var content = CacheHelper.GetContent("REGISTRATIONEMAIL");
if (content != null)
{
content.Text = context.Text.Replace("@@[email protected]@", registration.FullName);
return content.Text;
}
else return null;
}
CacheHelper.GetContent()
方法は静的であり、私はこれを行うことによって、この「バグ」を修正:
private string ProcessEmailBody(MyRegistrationModel registration)
{
var content = CacheHelper.GetContent("REGISTRATIONEMAIL");
if (content != null)
{
string body = content.Text;
body = body.Replace("@@[email protected]@", registration.FullName);
return body;
}
else return null;
}
そして、これが問題を修正した理由私は私の人生のために把握することはできません。誰にでもこれを見せてもらえますか?
EDIT:ここに私のGetContentメソッド()メソッド(私は簡単にされていた、署名は上記と異なることを知っている)
public static Content GetContent(string key, int partnerSiteId, int? version, IContentRepository contentRepository, out string cacheKey)
{
cacheKey = string.Format("{0}_{1}_{2}", key, partnerSiteId, version);
var content = CacheManager.Get(cacheKey,() => contentRepository.GetContent(key, partnerSiteId, version), WebConfig.GetCacheDuration(CacheProfile.Short));
return content;
}
private static DataCache _Cache = null; // DataCache is from AppFabric (Microsoft.ApplicationServer.Caching)
public static T Get<T>(string objectKey, Func<T> reloadItemExpresion, TimeSpan cacheDuration) where T : class
{
if (_Cache == null)
{
if (reloadItemExpresion != null)
{
return reloadItemExpresion.Invoke();
}
return null;
}
object cachedObject = null;
try
{
cachedObject = _Cache.Get(objectKey);
}
catch (Exception ex)
{
if (ex is FileNotFoundException)
{
_Cache.Remove(objectKey);
}
}
if (cachedObject != null)
{
return cachedObject as T;
}
if (reloadItemExpresion != null && cacheDuration > TimeSpan.Zero)
{
T item = reloadItemExpresion.Invoke();
if (item != null)
{
Insert(item, objectKey, cacheDuration);
}
return item;
}
return null;
}
contentRepository.GetContent
だけで、データベースへの消灯だと戻って実際のコンテンツをフェッチします。
「CacheHelper.GetContent」のコードを公開します...おそらく、複数のスレッド間でインスタンス*共有*を提供する可能性が高いため、content.Textを変更するときに競合条件を作成しています。 –
十分な情報がありません。コンテンツの実際のタイプは何ですか?'GetContent'メソッドはどのように実装されていますか?あなたは常に 'content'の同じインスタンスを渡しますか?このコードはマルチスレッドで動作しますか?その場合、これは単に競合状態になる可能性があり、適切なスレッド同期を確保する必要があります。 –
私は自分の質問を編集しました。 – eth0