5

私の ASP.NET MVC アプリケーションでは、すべての要求を順番に処理したいと考えています。アクション/コントローラー コードを別のコードと同時に実行する必要はありません。2 つの要求が同時に受信された場合、最初の要求が最初に実行され、最初の要求が完了したら 2 番目の要求が実行されます。

グローバルロック変数を使用する以外に、これを行うより良い方法はありますか?

編集: アプリケーションは、Web サービス呼び出しを実行し、データベースをクリーンアップする Web 上のバッチ/サービスです。サイト内の異なる URL は、異なるバッチ操作につながります。これはエンドユーザー向けのサイトではありません。したがって、URL への要求 (いくつかのバッチ操作を実行する) が一度に 1 つだけ実行されるようにする必要があります。そうしないと、バッチ操作のコードがそれ自体または他のバッチ操作と同時に実行されると、バッチ操作が破損する可能性があります。 . 実際、あるリクエストが現在実行されているときに別のリクエストが来た場合、前のリクエストが終了した後であっても、そのリクエストはまったく実行されるべきではありません。エラーメッセージが表示されるだけです。

コードではなく IIS でこれを行う方法があるかどうかを知りたいです。グローバルなロック変数を使用すると、コードがより複雑になり、ロック変数が true に設定されていても false に設定できないというデッドロックが発生する可能性があります。

EDIT:実装計画のサンプルコード

[HttpPost]
public ActionResult Batch1()
{
    //Config.Lock is a global static boolean variable
    if(Config.Lock) { Response.Write("Error: another batch process is running"); return View(); }
    Config.Lock = true; 

    //Run some batch calls and web services (this code cannot be interleaved with ExecuteBatchCode2() or itself)
    ExecuteBatchCode();

    Config.Lock = false;
    return View();
}

[HttpPost]
public ActionResult Batch2()
{
    if(Config.Lock) { Response.Write("Error: another batch process is running"); return View(); }
    Config.Lock = true;

    //Run some batch calls and web services (this code cannot be interleaved with ExecuteBatchCode1() or itself)
    ExecuteBatchCode2();

    Config.Lock = false;
    return View();
}

コードが Config.Lock = false に到達せず、Config.Lock = true が永遠に続き、リクエストが処理されなくなる場合について心配する必要がありますか?

4

3 に答える 3

6

あなたはできる限りリクエストを受け入れました。人々はブラウザの前で待つのが好きではありません。しかし、その後、サーブ側で、yuo はそれらを (たとえば) にプッシュしてQueue<T>、順番に処理することができます。

要するに:

  • 非同期で受け入れる
  • プロセス、サーバー上、順番に
于 2014-06-20T15:20:26.030 に答える
3

属性を書くことができます:

public class ExclusiveActionAttribute : ActionFilterAttribute
{
    private static int isExecuting = 0;
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Interlocked.CompareExchange(ref isExecuting, 1, 0) == 0)
        {
            base.OnActionExecuting(filterContext);   
            return; 
        }
        filterContext.Result = 
            new HttpStatusCodeResult(HttpStatusCode.ServiceUnavailable);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        base.OnResultExecuted(filterContext);
        Interlocked.Exchange(ref isExecuting, 0);
    }
}

次に、制御するコントローラー/メソッドで使用します。

[ExclusiveAction] //either here, for every action in the controller
public class MyController : Controller
{
    [ExclusiveAction] //or here for specific methods
    public ActionResult DoTheThing()
    {
        //foo
        return SomeActionResult();
    }
}
于 2014-06-20T16:03:49.203 に答える