1

停止するまでループし続けるWindowsサービスがあります。各ループの後、15 秒のスレッド間隔があります。以下に示すように、オブジェクトを解決するために Unity コンテナーを使用しています。

var processes = ProcessConfigurationSection.GetProcesses();
while (!_stopped)
{
    try
    {
        foreach (var process in processes)
        {
            var worker = new Worker(DiContainer.UnityContainer.Resolve<IProcessDao>());
            worker.RunProcess(process.Name, process.StoredProcedure, process.BatchSize);
        }
        Thread.Sleep(_interval);
    }
    catch (Exception ex)
    {
        Log.LogEvent(...);
    }
}

while ループ内でワーカーのインスタンスを作成 (およびオブジェクトを解決) する必要がありますか?それとも、パフォーマンスを向上させるために while ループの外に配置する必要がありますか? また、このアプローチのいずれかでメモリリークが発生する可能性はありますか?

4

1 に答える 1

1

通常、スコープは「リクエストごと」に定義する必要があります。Webアプリケーションの場合、これは通常、Web要求の存続期間中続くスコープになります。ただし、Windowsサービスアプリケーションの場合、まだ要求がありますが、要求として表示するものを決定する必要があるのはあなただけです。各RunProcess呼び出しは単一の要求(したがって単一のスコープ)である場合もprocessesあれば、バッチ全体の処理を単一の要求と見なす場合もあります。

スコープ付きライフスタイルは通常、リクエスト全体で再利用される作業単位の実装などを実装するため、このスコープをループの外側で定義しないでください。たとえば、EntityFrameworkDbContextは作業単位です。DbContext操作が失敗すると、が破損し、アプリケーション全体が破損する可能性があるため、アプリケーションの存続期間中は同じものを再利用したくないでしょうDbContext

Unityでは、スコープは子コンテナーを使用して実装されます。リクエストは次のようにラップする必要があります。

using (var child =
    DiContainer.UnityContainer.CreateChildContainer())
{
    var worker = new Worker(child.Resolve<IProcessDao>());
    worker.RunProcess(process.Name, process.StoredProcedure,
        process.BatchSize);
}

または、おそらくusing (var childをラップする必要がありforeachます。それはあなたが決めなければならないことです。

于 2013-03-05T15:26:33.737 に答える