0

所以基本上,我有一个控制器(SomeController.cs)方法,称之为Index(),我想防止两个本地和不同机器同时访问Index(),因为它涉及繁重的处理。这是我的控制器方法的样子

public ActionResult Index()
{
    ViewBag.controllerObj = this;
    if(! _Ready)
    {
        lock(_Locker)
        {
            if(!_Ready)
            {
                 ViewBag.canStart = true;
                 _Ready = true;
             }

         }
     }
 }

public bool canStart(ViewDataDictionary vd)
{
    // Override the controller's ViewData dictionary with the one passed from the view.
    ViewData = vd;

    Setting settings = data.Settings.FirstOrDefault();

    if (settings == null)
    {
        settings = new Setting();
        data.Settings.Add(settings);
        data.SaveChanges();
    }

    var starter = new Guid();
    data.Entry(settings).Reload();

    if (settings.startedBy.HasValue && settings.startedBy != starter)
    {
        return false;
    }

    settings.startedBy = starter;
    ViewBag.Settings = settings;
    data.SaveChanges();

    return true;
}

然后我在文件 Index.aspx 的顶部有以下内容

var canStart = false;
if(ViewBag.canStart != null)
{
    canStart = (bool)ViewBag.controllerObj.canStart(ViewData);
}

if(canStart)
{
    // Heavy duty processing
}

所以我的问题是,当我在同一浏览器的两个选项卡中导航到 Some/Index 时,Index.aspx 仍然可以一个接一个地访问。为什么会这样?当我在两种不同的浏览器中进行测试时,一种浏览器会继续处理,另一种则不会。

更新:

所以我删除了锁,只使用了一个在内存中共享的私有静态变量,而不是双重检查锁。如果两台不同的机器同时访问,我还会检查数据库表是否已更新。

4

1 回答 1

0

您可以使用 vollat​​ion 属性来执行此操作

private static volatile bool isExecuting = false;

public ActionResult Index()
{
   if(!isExecuting)
   {
      isExecuting = true;
      try
      {
          // Your instruction here.
      }
      finally
      {
         isExecuting = false;
      }          
   }
}

我认为这可能会解决您的问题。

于 2013-09-13T21:20:50.260 回答