0

このタスクを達成するための最良の方法を見つけようとしてきましたが、私が考えていることをできるだけ簡単に説明しようとします.

私は woot.com や whiskeymilitia.com などに似た Web サイトを扱っており、その日の取引または特定の時間制限のある IE: 15 分の取引があります。アプリケーションの起動時にx秒ごとに実行されるタイマーを作成しようとしています。たとえば、5秒ごとに実行し、取引時間制限が経過したかどうかを確認します。

現在、データベースにクエリを実行して、表示する必要があるアクティブな取引を取得していますが、これを Application_Start 内に実装する方法が完全にはわかりません。基本的には、取引と取引制限時間 + 経過時間をチェックし、その時点でその取引を非アクティブとしてフラグを立てるかどうかを決定します。アプリケーションの開始時に照会したモデルをコントローラーにルーティングすることは可能ですか?

これはここで私にとって新しい概念であり、確実な解決策を見つけたいと思っているので、どんな種類のアドバイスも素晴らしいでしょう!

必要に応じて、何でも明確にしてください。再度、感謝します :)

- 編集 -

SqlDependency を調べた後、すべてをテストするとエラーが発生しました。

現在のデータベースの SQL Server Service Broker が有効になっていないため、クエリ通知はサポートされていません。通知を使用する場合は、このデータベースの Service Broker を有効にしてください。ホストは、データベースで SQL Service Broker を有効にする必要があります。ほとんどの共有環境ホスティング会社は、専用サーバー環境向けであると述べて、これを避けるようです。

代替手段を探しています。同じことに遭遇する前に人々がピークに達するように、私はこれをやめると考えました。

-- 午後 8 時 30 分編集 --

そのため、この問題を解決するために Cache クラスを利用しようとしましたが、完全に立ち往生しています。

    public ActionResult Index()
    {            

        CurrentDealModel model = new CurrentDealModel();

        model.DealQueueDetails = db.FirstOrDefault<ProductQueue>("SELECT * FROM ProductQueue WHERE Active = 1");

        model.ProductDetails = db.FirstOrDefault<Product>("WHERE Id = @0", model.DealQueueDetails.ProductId);

        return View(model);
    }

変数 model.DealQueueDetails.DealTimeLimit に保存されている時間、このデータをコントローラーにキャッシュしたい - このソリューションの問題は、管理者が取引を表示する期間を決定することであり、キャッシュする必要があることを意味します。その値に。追加の助けを貸してくれる人がいるなら、私はとても感謝しています!

ジェームス・ジョンソンと私が試した他の人による

Cache.Insert("AbsoluteCacheKey", cacheData, null, DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration

ただし、モデルに cacheData を設定すると、NullReferenceException が返されます。はあ、なんでこんなに苦戦しなきゃいけないんだろう。

4

3 に答える 3

1

ASP.NET は、あらゆる種類のタイミング機能を実装するのに適切な場所ではありません。スケジュールされたタスクまたはサービスを使用するか、サーバー側のストレージ メディア (キャッシュ、アプリケーションなど) のいずれかに有効期限を保存し、すべての要求でそれを確認します。

SqlDependencyを使用したキャッシュをお勧めします: ASP.NET アプリケーションの SqlDependency

編集

a を使用することが検討されていない場合SqlDependencyは、絶対有効期限を設定してください。

Cache.Insert("AbsoluteCacheKey", cacheData, null, 
    DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration);
于 2012-05-09T14:15:54.470 に答える
0

よし、いじくり回して研究した 12 時間後、ようやくこれを正しく実装することができ、とてもうまく機能しています。

    public ActionResult Index()
    {

        ViewBag.Message = "Welcome to ASP.NET MVC!";

        CurrentDealModel model = new CurrentDealModel();

        model.DealQueueDetails = db.FirstOrDefault<ProductQueue>("SELECT * FROM ProductQueue WHERE Active = 1");

        model.ProductDetails = db.FirstOrDefault<Product>("WHERE Id = @0", model.DealQueueDetails.ProductId);
        var DealTime = model.DealQueueDetails.DealTimeLimit;
        var CurrentTime = System.DateTime.Now;

        TimeSpan span = DealTime.Subtract(CurrentTime);

        var model1 = HttpContext.Cache.Get(model.DealQueueDetails.Id.ToString());
        if (model1 == null)
        {
            model1 = HttpContext.Cache.Add(model.DealQueueDetails.Id.ToString(), model, null, System.DateTime.Now.Add(span).AddSeconds(10), Cache.NoSlidingExpiration, CacheItemPriority.High, new CacheItemRemovedCallback(RedirectToNewDeal));
            var CachedObject = HttpContext.Cache.Get(model.DealQueueDetails.Id.ToString());
            return View(CachedObject);
        }
        return View(model1);

    }

名前を変更する必要があるいくつかの変数と、これに関するいくつかのリファクタリングを除いて、完全に機能しています。次に、CacheItemRemovedCallback を以下の関数に設定します。

    public static void RedirectToNewDeal(String key, Object item, CacheItemRemovedReason reason) 
    {
        DatabaseEntitiesDB db = DatabaseEntitiesDB.GetInstance();

        if(reason.ToString() == "Expired")
        {
            var QueueToDisable = db.FirstOrDefault<ProductQueue>("WHERE Id = @0", key);
            QueueToDisable.Active = false;
            QueueToDisable.Update();
        }
    }

また、いくつかのエラー処理/ログのために、これにもいくつかのリファクタリングを行う必要がありますが、これは私が期待したとおりに機能しました. これ以外の唯一のことは、キャッシュをチェックするために 3 秒ごとにメイン内で AJAX ポーリング メソッドを呼び出す必要があることです。

     public ActionResult CacheCheck(string key)
    {
        var GetCachedObject = HttpContext.Cache.Get(key);

        if (GetCachedObject != null)
        {
            return Content("NotExpired");
        }
        return Content("Expired");

    }

AJAX 呼び出し

setTimeout(function () {
        setInterval(CacheCheck, 2000);
        CacheCheck();
    }, 10000);

function CacheCheck() {
        $.ajax({
            type: "POST",
            url: '@Url.Action("cachecheck", "home", new { key = Model.DealQueueDetails.Id })',
            success: function (data) {                    
                if (data == "Expired") {
                    window.location.reload();
                } 
            }
        })
    }

ページを更新して新しい契約を取得するためのより良い方法を誰かが知っているなら、私はすべて耳にします!

みんなと彼らの助けに感謝します。これが他の人にも役立つことを願っています!

于 2012-05-10T11:14:24.983 に答える
0

データベースにアクセスする必要がないように、現在の取引をキャッシュに保持することをお勧めします。しかし、それでは、必要に応じてどのように更新されるのでしょうか? 簡単な答えです。キャッシュの有効期限を取引が終了した絶対時間に設定して、新しい取引を見つけるためにデータベースにアクセスする必要があるようにします。

擬似コード:

  public Deal GetDeal()
  {
      if (Cache contains deal)
          return deal from cache;
      else
      {
          get deal
          add deal to cache with absolute expiration
      }   
  }

キャッシュを使用するには、次を参照してください。

この実装では、パフォーマンス、ポーリング、サーバーの再起動、依存関係などについて心配する必要はありません。

于 2012-05-09T18:14:29.543 に答える