ASP.NET MVC 4:只允许一次一个请求 [英] ASP.NET MVC 4: Only allow one request at a time

查看:192
本文介绍了ASP.NET MVC 4:只允许一次一个请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的ASP.NET MVC应用程序,我想继续处理所有的请求;无动作/控制器code应与另一种执行。如果两个请求在相似的时间进来,它应该首先运行第一位的,然后是第二个,当第一个完成。

In my ASP.NET MVC Application, I want to handle all requests sequentially; no action/controller code should be executed concurrently with another. If two requests come in at similar times, it should run the first one first, then the second one when the first one is done.

是否有这样做除了使用全局锁变量的一个更好的办法?

Is there a better way of doing this besides using a global lock variable?

编辑:应用程序在执行Web服务调用和清理数据库中的网页多批次/服务。不同的URL在站点导致不同的批处理操作。这不是为最终用户的站点。因此,我需要让这个只有一个请求到一个URL(这将做一些批处理操作),将在同一时间内完成,否则,如果code代表它本身同时运行,或批处理操作可能会损坏其他的批处理操作。事实上,如果还有其他​​请求到来时,一个是当前正在执行的,它不应该在所有的运行,即使是previous之一结束之后;它应该只是给出一个错误消息。

The application is more of a batch/service over the web that performs web service calls and cleans up a database. Different URLS in the site lead to different batch operations. This is not a site for end-users. Thus, I need to make it so that only one request to a URL (which will do some batch operations) will be done at a time, otherwise the batch operation could be corrupted if code for it runs concurrently with itself, or other batch operations. In fact, if another request comes when one is currently executing, it should not be run at all, even after the previous one finishes; it should just give an error message.

我想知道是否有办法在IIS做到这一点,而不是code。如果我有一个全局锁变量,它将使code更为复杂,我可能会在锁变量设置为true死锁运行,但绝不可以被设置为false。

I would like to know if there was a way to do this in IIS instead of code. If I have a global lock variable, it would make the code more complicated, and I might run in a deadlock where the lock variable is set to true but never can be set to false.

编辑:执行计划的样品code

Sample code of implementation plan

[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();
}

我将需要担心的情​​况下code没有达到Config.Lock =假,导致Config.Lock =真正的永远,导致送达没有更多的要求呢?

Would I need to be worried about a case where the code does not reach Config.Lock = false, resulting in Config.Lock = true forever, causing no more requests to be served?

推荐答案

您可以写一个属性:

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);
    }
}

然后使用它,你想控制的控制器/方法:

then use it on the controllers/methods that you want to control:

[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();
    }
}

这篇关于ASP.NET MVC 4:只允许一次一个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆