ConcurrentDictionary 显然无法在 ASP.NET 控制器中工作

ConcurrentDictionary apparently not working in ASP.NET controller

为什么并发字典的行为不像并发字典?

[Route("aaa")]
[HttpPost]
public Outbound Post(Inbound inbound)
{
    Outbound outbound = new Outbound();

    TaskState taskState = new TaskState();
    taskState.state = 0;

    TaskState s;
    bool rc = taskDictionary.TryGetValue(inbound.taskId, out s);
    if (rc == false)
        taskDictionary.GetOrAdd(inbound.taskId, taskState);
    else
        return null;
    if (s != null)
        return null;

    rc = taskDictionary.TryGetValue(inbound.taskId, out s);
    if (rc)
    {
        string m0 = String.Format("POST dictionary count is " + taskDictionary.Count);
        _logger.Log(LogLevel.Error, m0);
    }
    else
        return null;

    _logger.Log(LogLevel.Error, "POST method is doing long running work.");

    long Billion = 1000000000;
    // work quantity 5 means about 26 seconds // 30 billion is 215 seconds
    for (long i = 0; i < inbound.WorkQuantity * Billion; i++)
        ;
    outbound.Message = "The server did some work.";
    outbound.BigObject = Modify(inbound.BigObject);

    _logger.Log(LogLevel.Error, "POST finished long running work and will soon remove from the dictionary.");

    rc = taskDictionary.Remove(inbound.taskId, out s);
    if (rc == false)
        return null;
    if (s == null)
        return null;

    _logger.Log(LogLevel.Error, "POST is returning the object.");

    return outbound;
}
[Route("bbb")]
[HttpPost]
public TaskState PostState(TaskId taskId)
{
    TaskState s;
    if (taskDictionary.TryGetValue(taskId, out s))
    {
        _logger.Log(LogLevel.Error, "POSTSTATE, state is " + s.AsString());
        return s;
    }
    else
    {
        _logger.Log(LogLevel.Error, "POSTSTATE, state not found, dictionary count is " + taskDictionary.Count);
        return null;
    }
}



TaskDictionary taskDictionary = new TaskDictionary();
class TaskDictionary : ConcurrentDictionary<TaskId, TaskState>
{
    internal bool IncrementState(TaskId taskId)
    {
        TaskState s;
        if (TryGetValue(taskId, out s))
        {
            s.Increment();
            return true;
        }
        else
            return false;
    }
}

日志输出是...

12.207 +00:00 [Error] MyController: POST dictionary count is 1
12.322 +00:00 [Error] MyController: POST method is doing long running work.
14.361 +00:00 [Error] MyController: POSTSTATE, state not found, dictionary count is 0
40.452 +00:00 [Error] MyController: POST finished long running work and will soon remove from the dictionary.
40.569 +00:00 [Error] MyController: POST is returning the object.

具体问题是状态信息请求不起作用,因为字典显示为空。

因此,根据您正在执行的日志记录输出,两个 post 请求生成您向我们展示的输出。

你初始化并发字典的方式,就是为什么它在第二个请求上 returns null 的原因。这与应用程序 接收 这些请求的方式有关。对您应用的每个请求都独立于另一个请求。

简单地说;

一个用户 POST 给你的应用。 请求通过中间件管道,最终将到达您的控制器。现在,这是重要的部分,控制器将为这个特定请求 'constructed' 。它将在请求期间存在。这是因为默认情况下,控制器的生命周期是有范围的。所以下一个请求,将构建一个新的控制器,这意味着字典与第一个不同。

因此,为了克服这个范围请求问题,您创建了一个 service that contains the dictionary, register this as a singleton (meaning it will only be constructed once and then it's shared), and use dependency injection 以在控制器中使用它。