2012-04-30 16 views
6

私は現在電子商取引サイトで作業していますが、実装方法がわからないという1つの機能があります。ほとんどの場合、カートに商品を追加して購入するだけですが、これはおそらく最も単純なワークフローです。私は何を求めているのかは少し異なります。購入する製品に期限がある場合はどうなりますか?私はいくつかのサイトは、サッカーマネージャーのような製品を購入する正確な時間制限を与えることを意味し、あなたは永遠に製品を保持することはできませんこれらのサイトでは、それの15分の制限があり、その期間で購入しない場合は、あなたのカートから解放される。 (そしておそらく他の誰かがそれに飛びつくでしょう)ASP.NET MVC 3サイトでバックグラウンドジョブを実行する方法は?

今、ASP.NET MVCプログラマとして、私はこの機能を実装したいと思いますが、私が言ったように、私はそれを行う方法がわかりません。私はカートにアイテムを追加するときに、時間(ItemAddedAtのようなもの)を保持する必要があると思います。そのアイテムをx分後にリリースする必要があり、その製品をリリースするのにx分後に実行する必要があります。グローバルに考えると、私はサービスを必要と思う、私はアイテムを追加すると、私はまた、このサービスに加入する必要があり、サービスはバックグラウンドでタイマー/ジョブを実行します。私が知らない/経験がない部分は、ASP.NET MVCプロジェクトでこれを行う方法ですが、そこにはサンプルプロジェクト、記事、ライブラリなどがありますか?

私のロジックがこの問題に適しているかどうかは分かりませんが、可能であれば、いくつかの指針が必要です。

答えて

4

AFAIK MVCプロジェクト内でタスクを宣言/プログラムする標準的な方法はありません。必要な目的を達成するための推奨される方法は、ソリューション内に新しいコンソールアプリケーションプロジェクトを作成し、Windowsタスクスケジューラを使用してX分ごとに実行し、任意のカートでX分以上経過した製品をリリースすることです。

これを行うには、MVCプロジェクトを新しいモデルから参照するか(すべてのモデルにアクセスするために)、さらにはクラスライブラリプロジェクトを作成し、そこでモデル/データベースクラスを移動し、それをMVCプロジェクトやConsoleプロジェクトから参照してください。


実際には、MVCプロジェクトでプログラムされたタスクを取得するために使用できる小さな「ハック」があります。キャッシュへの「タスク」のエントリを追加することになり、Global.asaxのから、例えば、

HttpContext.Current.Cache.Add("Task", "1", null, 
      DateTime.MaxValue, TimeSpan.FromMinutes(5), 
      CacheItemPriority.Normal, new CacheItemRemovedCallback(CheckCarts)); 

その行、呼び出すことができます:あなたは、次のコードを使用することができます。保存された値( "1")は重要ではありません。重要なのは、キャッシュエントリが5分で失効し、期限が切れたときに、 "CheckCarts"メソッド(Global.asaxで定義されています。このコード)。

public void CheckCarts(string key, object value, CacheItemRemovedReason reason) { 
    // Insert your code here to check for expired carts 
    (...) 

    // We add the entry again to the cache, so that this method will be called again in 5 minutes. 
    HttpContext.Current.Cache.Add("Task", "1", null, 
      DateTime.MaxValue, TimeSpan.FromMinutes(5), 
      CacheItemPriority.Normal, new CacheItemRemovedCallback(CheckCarts)); 
} 

キャッシュの有効期限が切れ、CheckCartsメソッドが呼び出され、あなたのコードは、それが関係しているものは何でもない、そして最後に、別の5分で呼ばれるように、再びキャッシュに自分自身を追加します。

+0

まずは、詳細な説明のおかげで^^ 私はWindowsタスクスケジューラを好まないと思います。私がスケジューラを使っていれば、非常に短期間で有効期限と次回の予定実行時間との間には大きな時間差があります。 IMHO正確なトリガーを提供し、簡単に実装できるように見えるので、2番目のソリューションはもっとエキサイティングですが、私の考えではこのようなソリューションで使用するには十分信頼できるCacheItemRemovedCallbackですか? –

+0

そのような再帰的な実装も同様に機能するかもしれませんが、私はすぐにこのケースでコールスタックサイズを心配し始めました –

+0

@ArtemNikolov実際には、まったく同じ理由でこのコードを使用しました。株式を解放する)、それは約4年間実行されているので、私はそう思います:) – salgiza

3

このシナリオでは、signalRを叫ぶだけです。 これは簡単な方法であなたが求めていることを行うことを可能にします。

カート内のアイテムの有効期限が切れている場合は、期限切れのアイテムがあれば閲覧閲覧を行うことができます。あなたが持っている場合は、そのアイテムの削除コードを実行してあなたのUIを更新することができます。

+1

私は同意します。あなたのカートを見るまで、取り外しは問題ではありません。だから、なぜこのバックグラウンドプロセスを実行するのですか?それを表示する前に、カートが期限切れであることを確認してください。これにより、放棄されたカートの期限切れ作業も省くことができます。バッチ・ジョブを監視して、実行中であることを確認する必要がありません。 –

+0

@spaceman:私はここでうまくいくかもしれないリアルタイムライブラリーであるSignalRについて調べてみましょう。あなたは素敵なUXトリックをやることができます。 –

+0

@ブライアン:私はこの削除について少し誤解があると思います。これは買い手のカートではなく、その商品の在庫です。有効期限が切れた後は、他の人が購入できるようにその商品をリリースする必要があります。その時点まで、アイテムはまだ予約されているため、無効な購入ボタンを表示する必要があります。もちろん、リクエストごとに在庫を確認する必要がありますが、在庫管理サービスでは予約済みアイテムの有効期限も確認する必要があります。その代わりに、その製品が有効期限を知らせるようにして、コンポーネント間の内部メッセージングを減らすことができます。 –

関連する問題