我如何prevent在同一请求工作的多个后台进程的创建? [英] How do I prevent the creation of multiple background processes working on the same request?

查看:131
本文介绍了我如何prevent在同一请求工作的多个后台进程的创建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个目的,就是一个简单的WebAPI控制器的方法是引发一些后台处理,并立即返回202接受响应(而不必完成后台处理的是一个202的响应是一致的。)

 公共异步任务< IHttpActionResult> DoSomething的(字符串ID)
{
    HostingEnvironment.QueueBackgroundWorkItem(异步克拉=>
    {
        //做工作
    }
    返回ResponseMessage(新的Htt presponseMessage(的HTTPStatus code.Accepted));
}

不过,我希望能够为prevent多个请求使用相同的ID在同一端点同时从引发相同的后台处理的多个实例。

事实上,如果具有相同ID的两个请求都将在同一时间(或接近不够)提出,第一个会做处理该ID,第二个将能够确定这一点,并采取相应的行动而不是重复这已经正在开展的工作。

我想避免数据库/持久化存储,如果在所有可能的,我知道的IIS工作进程内运行的异步任务的风险 - 为参数的缘故,后台处理并不重要<。 / p>

我怎么能去这样做?任何帮助将是非常美联社preciated。


解决方案

您将需要某种形式的所有可能的工人之间的共享存储。这可以是,例如:


  • 的静态变量。可能是最容易实现,但也有局限性,当应用程序不会只在一个AppDomain中运行(如果你想扩展尤为重要)。所以可能不是最好的办法

  • SQL数据库:可能是最常见的一种。如果您的应用程序已经使用了一个,我会说去这条路线。

  • 系统无SQL数据库,例如key-value存储。可能是一种选择,如果您的应用程序不使用SQL数据库呢。

  • 某些外部组件,例如工作流管理工具

编辑:
例如,使用 ConcurrentDictionary (每请求螺纹起动机 - 我还是老样子认为使用(可能的NoSQL)数据库将是最优雅的方式) - 实际上你可以只是把任务到字典:

 私人ConcurrentDictionary&LT;字符串,任务&LT;&SOMETYPE GT;&GT; _cache =新// ...VAR任务= _cache.GetOrAdd(&LT;关键&gt;中,重点= GT; Task.Run(()=&GT; / *做一些工作* /));
如果(task.IsCompleted)
   / *结果就绪* /;
其他
   / *必须等待* /;

I have a simple WebApi controller method that's purpose is to trigger some background processing and return a 202 Accepted response immediately (without necessarily having completed the background processing as is consistent with a 202 response.)

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

However, I want to be able to prevent multiple requests to the same endpoint with the same id from triggering multiple instances of the same background processing simultaneously.

Effectively, if two requests with the same id's were to be made at the same time (or near enough), the first one would do the processing for that id and the second one would be able to identify this and take action accordingly and not duplicate the work that's already being done.

I'd like to avoid databases/persistent storage if at all possible and I'm aware of the risks of running async tasks within an IIS worker process - for the sake of the argument, the background processing is not critical.

How can I go about doing this? Any help would be much appreciated.

解决方案

You'll need some kind of storage shared between all your possible workers. This could be, for example:

  • A static variable. Probably the easiest to implement, but has limitations when the application does not run in only one AppDomain (especially important if you want to scale). So probably not the best way
  • An SQL Database: Probably the most common one. If your application already uses one, I'd say go for this route.
  • A No-SQL database, for example a key-value store. Might be an alternative if your application does not use a SQL database yet.
  • Some external component such a workflow management tool

EDIT: Example using ConcurrentDictionary (per request of the thread starter - I stil think using a (possibly NoSQL) database would be the most elegant way) - actually you could just put Tasks into the dictionary:

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*/;

这篇关于我如何prevent在同一请求工作的多个后台进程的创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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