クエリの結果に基づいて、必要に応じてレコードを処理し、Azureサービスバスメッセージを送信するワーカーロールがあります。これは基本的にキュー処理サービスです。SQL Azureを使用するためのベストプラクティスの一部として、すべてのクエリステートメントを再試行ポリシーでラップしました(これにより、一時的なエラーが検出され、定義されたポリシーに基づいて再試行されます)。実際にはusingステートメント内からメッセージを送信するため、db変数の「リーク」はありません。
usingステートメント内で、ReSharperは「Accessto Disposed Closure」警告をスローします。これは、おそらく、再試行ポリシーのfuncパラメーターとしてDataContextを渡しているためです。
私の質問は、ReSharperがこのパターンを正しく検出していないという私の仮定で大丈夫ですか、それとも上記の警告を防ぐためにこれらの関数を記述する方法に代替方法がありますか?
コード
restartPolicy.ExecuteActionのdb変数は、フラグが立てられているものです。
using (var db = new MyEntities())
{
var thingsToUpdate = retryPolicy.ExecuteAction(() => db.QueueTable.Where(x => x.UpdateType == "UpdateType" && x.DueNext < DateTime.UtcNow).Take(30).ToList());
if (!thingsToUpdate.Any())
{
return;
}
while (thingsToUpdate.Any())
{
var message = new ServiceMessage{
Type = "UpdateType",
Requests = thingsToUpdate.Select(x => new ServiceMessageRequest
{
LastRan = x.LastRan,
ParentItemId = x.ThingId,
OwnerId = x.Thing.ForiegnKeyid
}).ToList()
};
SendMessage("UpdateType", message);
foreach (var thing in thingsToUpdate )
{
thing.LastRan = DateTime.UtcNow;
thing.DueNext = DateTime.UtcNow.AddMinutes(10);
}
retryPolicy.ExecuteAction(() => db.SaveChanges());
thingsToUpdate = db.QueueTable.Where(x => x.UpdateType == "UpdateType" && x.DueNext < DateTime.UtcNow).Take(30).ToList());
}
}
追加情報
私はまた、より多くの聴衆のためにこれをReSharperフォーラムに投稿しました、そしてこの特定の問題はそこでもう少し詳細に扱われました。後世のために、あなたはここで質問を見つけることができます。