【问题标题】:ASP.NET Core WebApi return response after queue processing队列处理后的 ASP.NET Core WebApi 返回响应
【发布时间】:2018-11-16 18:58:15
【问题描述】:

我有一个端点,它将一些实体作为 POST,称为 Entry。这些条目有一个名为 OrderNumber 的属性,它是一个从 1 到 n 的数字,根据今天已经发生的条目确定。因此,当数据库中有 100 个当天的条目时,新的 OrderNumber 应该是 101。

那么当您从不同的设备(X 和 Y)两次点击端点时会发生什么:

X。发送条目

X。向数据库询问当前条目 -> 以 100 响应

是的。发送条目

是的。向数据库询问当前条目 -> 以 100 响应

X。将使用 OrderNumber 101 插入记录

是的。将使用 OrderNumber 101 插入记录

我的解决方案是创建一个带有队列的后台任务(如此处所示:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1#queued-background-tasks)并在那里创建条目以确保它们被一个接一个地处理。

现在我的控制器中的问题是,我无法在请求期间返回具有正确 OrderNumber 的最新条目,因为每当队列处理此条目时都会发生这种情况。

那么客户端如何正确获取响应?还是有更好/不同的方法来处理这些情况?

【问题讨论】:

  • 您对数据库中发生的事情有任何控制权吗?我的意思是,您是否有权修改发生在数据库级别的插入?
  • 订单号是如何创建的?代码,数据库插入?
  • 是的,我可以控制这个数字。我不希望它是数据库生成的。这些数字是通过获取给定日期的最新数字 + 1 来创建的。

标签: c# asp.net-core concurrency background-process


【解决方案1】:

此处自定义属性代码:

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);
    }
}

通过在控制器的动作端点上添加[SingleThread] 属性,如果同时进行多个调用,它们将同时被处理一个,等待上一个调用释放锁。

这可能是您的情况的解决方案。

【讨论】:

  • 嗯,我刚试过,但有时会收到此错误:System.Threading.SynchronizationLockException: 'Object synchronization method was called from an unsynchronized block of code.'
【解决方案2】:

我刚刚找到了这个似乎可以解决我的问题的 stackoverflow 答案:

How to protect resources that may be used in a multi-threaded or async environment?

【讨论】:

    猜你喜欢
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多