C# 如何防止MVC控制器中的并发访问?

C# 如何防止MVC控制器中的并发访问?,c#,.net,asp.net-mvc,asp.net-mvc-4,C#,.net,Asp.net Mvc,Asp.net Mvc 4,我有一个可以通过特定URL访问的MVC控制器,当调用它时,它会运行一系列耗时的过程(从数据库中后期处理数据) 我需要确保当用户调用该方法时,该过程只启动一次。如果任何其他用户在后处理运行时访问该特定URL,则不会同时进行后处理 我的问题是: 我应该在C#中使用吗 我是否应该在DB中使用类似inProgress的标志,以便标记处理的开始和结束时间 还有其他解决办法吗 更确切地说:它们是线程安全的,因为控制器是为每个请求创建的。2个请求不共享一个控制器。每个并发请求都有自己的线程 这是使线程安全所

我有一个可以通过特定URL访问的MVC控制器,当调用它时,它会运行一系列耗时的过程(从数据库中后期处理数据)

我需要确保当用户调用该方法时,该过程只启动一次。如果任何其他用户在后处理运行时访问该特定URL,则不会同时进行后处理

我的问题是:

  • 我应该在C#中使用吗
  • 我是否应该在DB中使用类似inProgress的标志,以便标记处理的开始和结束时间
  • 还有其他解决办法吗

  • 更确切地说:它们是线程安全的,因为控制器是为每个请求创建的。2个请求不共享一个控制器。

    每个并发请求都有自己的线程

    这是使线程安全所需的一组正在进行的任务。此资源将是共享的,因此多个web请求将尝试同时访问

    在.NET4.0以后的版本中有并发集合,这使您的生活更加轻松。您需要的是一个并发集,但是不存在这样的类。您可以改用ConcurrentDictionary,只使用请求ID的键


    这假设您只有一台web服务器,否则您将需要一个数据库或共享服务解决方案。

    如果您想扩展到多台计算机,内存中的锁不是一个选项,但数据库中的锁可能是最简单的

    例如,您可以创建具有唯一id字段的锁表。收到请求时,请尝试插入id为1的行。如果成功,请进行后处理并删除密钥


    任何其他在另一次运行期间尝试插入密钥的请求都会导致插入失败,而不会运行作业。

    “线程安全”和“自动阻止并发访问”不一定是同一回事。有趣的是:@GibboK是的,但是引入性能问题或死锁会更容易,所以我不建议这样做。“每个并发请求都有自己的线程。”-有点错误-每个请求都由唯一的控制器实例处理,这些控制器实例在实际执行代码时租用可用线程,这对于现代(MVC4+)来说尤其如此使用异步控制器编写代码,其中多个并发请求可能会在同一线程上运行,而另一个线程正在“等待”。@GibboK-锁定时要非常小心-通常情况下,您应该使用
    lock
    来实现快速可预测的操作,而不是在几乎无限执行的情况下减慢一次(如网络或数据库访问).@AlexeiLevenkov如果一个请求正在等待,那么它不会与另一个正在运行的请求并发requests@GibboK锁定db在您的情况下可能更合适(正如Joachim Isaksson的回答所建议的那样)-您希望标记“这部分工作已经完成”-因此将该信息存储在与“工作”相关的其余数据的位置”“是的。也就是说,在内存结构的情况下,
    通常是一个很好的解决方案,外部数据(特别是可能被多个进程使用)进程内状态可能不合适。回答文章的标题。更确切地说,控制器的方法/实例数据不是一般意义上的“线程安全的”(如“可以随时从任何线程访问”),而是本身没有线程安全问题。请注意,问题主体讨论的是完全不同的问题(确保特定的请求只运行一个实例)。这是迄今为止我所见过的确保web应用程序中在任何时候只运行一个进程的最简单方法,我已经仔细研究了提供单个作业运行进程的不同方法。