1

私はC#5.0、VS 2012、MVC4を使用しています。従業員情報の検索を実行するときに、従業員データをキャッシュし、キャッシュを照会する必要があるシナリオがあります。

最初はすべての従業員を表示していませんが、すべての従業員をキャッシュするスレッドを開始したいと思いました。だから、ビューが表示されているときのインデックス方式では、これをやっています

       //Starting a thread to load the cache if its null
        if (HttpRuntime.Cache["AllEmployees"] == null)
        {
            thCacheAllEmployees = new Thread(new ThreadStart(CacheAllEmployees));
            thCacheAllEmployees.Name = "CacheAllEmployees";
            thCacheAllEmployees.Start();
        }

CacheAllEmployeesは、LDAPを照会し、すべての従業員をキャッシュに格納する別個のメソッドです。LDAPクエリには約15秒かかります。しかし、ビューがロードされ、キャッシュがまだロードされていない最初の15秒以内に、ユーザーが検索ボックスに入力を開始すると、GetFilteredEmployeesアクションメソッドへのajaxメソッド呼び出しを行います。以前に開始したスレッドにアクセスし、そのスレッドが有効かどうかを確認してから、そのスレッドが完了するのを待って、新しいLDAPクエリを再度実行する必要がないようにします。

      if (thCacheAllEmployees.IsAlive)
        {
            thCacheAllEmployees.Join();

            if (HttpRuntime.Cache["AllEmployees"] != null)
                return (List<CMSUser>)HttpRuntime.Cache["AllEmployees"];
        }

しかし、問題は、そのajax呼び出しが新しいメインスレッドであるように見え、thCacheAllEmployeesについて知らない場合です。したがって、thCacheAllEmployeesはnullオブジェクトになります。したがって、アプリケーション内の現在アクティブなすべてのスレッドからこのスレッドのインスタンスを取得する必要があります。

ビューが最初にセッション変数にロードされるときにthCacheAllEmployeesのスレッドIDを格納できますが、ajaxメソッド呼び出しを行うときにスレッドのプールからそのスレッドにアクセスするにはどうすればよいですか?

これを行うためのより良い方法はありますか?提案をお願いします。

4

2 に答える 2

0

データをキャッシュする最初の呼び出しを待つのはなぜですか?これは、アプリケーションの起動時に、のApplication_Start関数に追加することで実行できますGlobal.asax

これは、アプリケーションの開始時に15秒のオーバーヘッドがあることを意味しますが、その後は問題ありません。

ここでもスレッドを使用したい場合は、そのIDを静的変数に入れ、それを使用してリストがロードされているかどうかを確認できます。

于 2012-11-08T04:17:43.280 に答える
0

スレッドがデータではなくアクションを考えると考えるとき。データを保存する場合は、そのデータをスレッドに配置せずにメモリに配置すると、スコープに応じて1つ以上のスレッドからそのメモリにアクセスできるようになります。

そのデータを保存する方法はたくさんあります。キャッシュするデータがユーザーセッションごとに一意であるのか、グローバルキャッシュが1つだけ必要なのかわかりません。静的変数に入れることができるどこからでもアクセスしたいもの。複数のスレッドが同時にそのデータにアクセスしようとしないように、必ずロックを使用する必要があります。これは決して安全ではありません。


モデル

public static class MyCache
{
     private static object LockToken = new object(); 
     private static List<CMSUser> _Users { get; set; }

     static MyCache()
     {
        _Users = GetUsers();
     }

     public static List<CMSUser> Users
     {
          lock (LockToken)
          {
               return _Users;
          }
     }
}

コントローラ

public class UsersController : ApiController
{
    public List<CMSUser> Get()
    {
        return MyCache.Users;
    }
}

意見

$.ajax({
    url: '/api/users',
    dataType: 'json',
    success: function(users) {
        // do something with users here
    }
});
于 2012-11-08T04:27:55.047 に答える