c# - 如何防止创建处理同一请求的多个后台进程?

标签 c# asp.net multithreading asp.net-web-api2

我有一个简单的 WebApi Controller 方法,其目的是触发一些后台处理并立即返回 202 已接受响应(不必完成与 202 响应一致的后台处理。)

public async Task<IHttpActionResult> DoSomething(string id)
{
    HostingEnvironment.QueueBackgroundWorkItem(async ct =>
    {
        //Do work
    }
    return ResponseMessage(new HttpResponseMessage(HttpStatusCode.Accepted));
}

但是,我希望能够防止对具有相同 ID 的同一端点的多个请求同时触发同一后台处理的多个实例。

实际上,如果同时(或足够接近)发出具有相同 ID 的两个请求,第一个请求将处理该 ID,第二个将能够识别并采取相应的行动而不是重复已经完成的工作。

如果可能的话,我想避免使用数据库/持久存储,并且我知道在 IIS 工作进程中运行异步任务的风险——为了论证,后台处理并不重要。

我该怎么做呢?任何帮助将不胜感激。

最佳答案

您需要在所有可能的工作人员之间共享某种存储空间。这可能是,例如:

  • 静态变量。可能是最容易实现的,但当应用程序不只在一个 AppDomain 中运行时会有限制(如果你想扩展,这一点尤其重要)。所以可能不是最好的方法
  • 一个 SQL 数据库:可能是最常见的一个。如果您的应用程序已经使用了一个,我会说走这条路。
  • No-SQL 数据库,例如键值存储。如果您的应用程序尚未使用 SQL 数据库,则可能是替代方案。
  • 一些外部组件,例如工作流管理工具

编辑: 使用 ConcurrentDictionary 的示例(根据线程启动器的请求 - 我仍然认为使用(可能是 NoSQL)数据库将是最优雅的方式) - 实际上你可以将任务放入字典中:

private ConcurrentDictionary<string, Task<SomeType>> _cache = new //...

var task = _cache.GetOrAdd("<Key>", key => Task.Run(() => /*do some work*/));
if (task.IsCompleted)
   /*result ready*/;
else
   /*have to wait*/;

关于c# - 如何防止创建处理同一请求的多个后台进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34662403/

相关文章:

c# - 将 Firebird 连接到 ASP.net WebAPI 项目

c# - Visual Studio 2019 中没有 Razor 组件模板

python - 使用 Paho MQTT 在 Python 中订阅 MQTT 时出现线程问题

ios - appWillEnterForeground : is being called before appDidEnterBackground: finishes

c# - Windows ML 学习模型是否可以通过 UWP 之外的 C# 访问?

c# - 在 C# 中使用递归时,代码是线性处理还是伪并行处理?

asp.net - 缓存 VS session VS cookie?

C#线程同步

c# - 构建时的 NuGet 包还原速度极慢(每个项目约 10 秒)

c# - 是否有 Visual Studio 键盘快捷键来实现委托(delegate)?