简体   繁体   English

队列处理后ASP.NET Core WebApi返回响应

[英]ASP.NET Core WebApi return response after queue processing

I have an endpoint which takes some entity as POST called Entry. 我有一个将某些实体称为POST的终结点,称为Entry。 These entries have a property called OrderNumber which is a number from 1-n determined based on entries that already happened today. 这些条目具有一个名为OrderNumber的属性,该属性是一个1-n的数字,该数字基于今天已经发生的条目确定。 So when there are 100 entries in the database for the current day, the new OrderNumber should be 101. 因此,当数据库中当天有100个条目时,新的OrderNumber应该为101。

So what happens when you hit the endpoint twice from different devices (X and Y): 因此,当您从不同的设备(X和Y)两次击中端点时会发生什么:

X. Sends an entry X.发送一个条目

X. Asks database for current entries -> response with 100 X.向数据库询问当前条目->响应为100

Y. Sends an entry Y.发送条目

Y. Asks database for current entries -> response with 100 Y.向数据库询问当前条目->响应为100

X. Record will be inserted with OrderNumber 101 X.记录将插入订单号101

Y. Record will be inserted with OrderNumber 101 Y.记录将插入订单号101

My solution is to create a background task with a queue (as seen here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1#queued-background-tasks ) and create the entry there to ensure they are processed one after another. 我的解决方案是使用队列创建后台任务(如此处所示: https//docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/hosted-services?view = aspnetcore-2.1#queued- background-tasks )并在此处创建条目,以确保它们被依次处理。

Now the problem in my controller is, that I can't return the latest entry, with the proper OrderNumber during the request, because it happens whenever the queue has processed this entry. 现在,控制器中的问题是,在请求期间,我无法返回带有正确的OrderNumber的最新条目,因为只要队列处理了该条目,它就会发生。

So how does the client get the response back properly? 那么客户端如何正确地获得响应呢? Or is there a better/different way to handle these cases? 还是有更好/不同的方式来处理这些情况?

Custom attribute code here : 自定义属性代码在这里:

public class SingleThreadAttribute : ActionFilterAttribute
{
    private static Object _thisLock = new Object();

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        Monitor.Enter(_thisLock);
        base.OnActionExecuting(context);
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        base.OnActionExecuted(context);
        Monitor.Exit(_thisLock);
    }
}

By adding [SingleThread] attribute on your controller's action endpoint, if multiple calls are made at the same time, they would be process one at the time waiting for the lock to be released by the previous call. 通过在控制器的动作端点上添加[SingleThread]属性,如果同时进行多个调用,则它们将在等待上一个调用释放锁的同时被处理。

This could be a solution to your case. 这可以解决您的情况。

I just found this stackoverflow answer which seem to resolve my issue: 我刚刚找到了这个stackoverflow答案,似乎可以解决我的问题:

How to protect resources that may be used in a multi-threaded or async environment? 如何保护可能在多线程或异步环境中使用的资源?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM