0

新しいスレッドをトリガーして新しい値を設定しながら、古い値を提供するようにinprocMVCキャッシュを拡張しようとしています。

次のコードは、次の行を削除すると「機能」します。

ThreadPool.QueueUserWorkItem(delegate

「動作する」とは、キャッシュのリロードをトリガーしたリクエストを行ったクライアントが、キャッシュが更新されるまでブロックされることを意味しますが、他のすべてのクライアントはシャドウバージョンに対してロードを続けます。

理想的には、バックグラウンドで処理を実行し、キャッシュの更新をトリガーしたクライアントがその要求にシャドウコピーを使用するようにします。スレッドが完了した後で将来の要求を行うと、新しいキャッシュ値が提供されます。

私のソリューションは、DIフレームワークとしてCastleに大きく依存しています。私が抱えている問題は、CastleのLifeStylesに関係していると思います。エラーメッセージは次のとおりです。

HttpContext.Currentはnullです。PerWebRequestLifestyleはASP.Netでのみ使用できます

例外は、必要なコンポーネントを解決しようとしているときに、長時間実行されるプロセス( getCacheItem() )の奥深くで発生します。

私のキャッシュ方法は次のとおりです。

public T GetShadow<T>(string key, Func<T> getCacheItem, int timeOut)
{
    if (Exists(key))
    {
        _log.Info("Shadow: Returning item from Cache: " + key);
        return (T)HttpContext.Current.Cache[key];
    }

    var shadowKey = key + "-shadow";

    if (Monitor.TryEnter(GetKeyLock(key)))
    {
        ThreadPool.QueueUserWorkItem(delegate
        {
            try
            {
                var item = getCacheItem(); // Long running query

                // Replace the cache entry
                HttpRuntime.Cache.Insert(key, item, null,
                                    DateTime.UtcNow.AddMinutes(
                                           timeOut), Cache.NoSlidingExpiration);

                // And add its shadow for subsequent updates
                HttpRuntime.Cache.Insert(shadowKey, item, null,
                                    DateTime.UtcNow.AddMinutes(timeOut * 2), Cache.NoSlidingExpiration);
            }
            finally
            {
                Monitor.Exit(GetKeyLock(key));
            }
        });
    }

    while (!Exists(shadowKey))
    {
        Thread.Sleep(500);
    }

    return (T)HttpContext.Current.Cache[shadowKey];
}

だから私の質問は、MVC3内でスレッドの作成を正しく行っているかということです。

PWRのライフスタイルのためにウィンザーが例外をスローしないように、このシナリオでスレッドをスピンアップするためのより良い方法はありますか?

4

1 に答える 1

3

だから私の質問は、MVC3内でスレッドの作成を正しく行っているかということです。

いいえ、HttpContext.CurrentASP.NETアプリケーションのバックグラウンドスレッド内で使用しています。あなたの問題はWindsorやASP.NETMVCとは何の関係もありません。これは、バックグラウンドスレッド(名前が示すように)がユーザーのHTTPコンテキストの外部でバックグラウンドで実行される可能性があるため、単純に実行できないことです。したがって、そのようなスレッド内でこのコンテキストにアクセスしようとしても意味がありません。

ASP.NETとは独立して使用するように設計された新しいMemoryCacheクラスのおかげで、.NET4.0の新しいキャッシュ機能を使用できます。

于 2012-07-03T06:40:50.803 に答える