Asp.net core ConcurrentDictionary显然无法在ASP.NET控制器中工作
为什么并发字典的行为不像并发字典Asp.net core ConcurrentDictionary显然无法在ASP.NET控制器中工作,asp.net-core,concurrentdictionary,Asp.net Core,Concurrentdictionary,为什么并发字典的行为不像并发字典 [Route("aaa")] [HttpPost] public Outbound Post(Inbound inbound) { Outbound outbound = new Outbound(); TaskState taskState = new TaskState(); taskState.state = 0; TaskState s; bool rc = taskDictionary.T
[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;
}
}
具体地说,问题是对状态信息的请求不起作用,因为字典显示为空。因此,根据日志记录输出,您正在执行两个post请求,以生成显示给我们的输出 初始化并发字典的方式是它在第二次请求时返回null的原因。这与应用程序如何接收这些请求有关。对应用程序的每个请求都独立于另一个请求 简而言之 用户向你的应用发布的帖子。 请求通过中间件管道,最终将到达您的控制器。现在,这里是重要的部分,控制器将针对这个特定的请求进行“构造”。它将在请求期间有效。这是因为默认情况下控制器的生存期是限定范围的。因此,下一个请求将构造一个新的控制器,这意味着字典与第一个不同
因此,为了克服这个作用域请求问题,您创建了一个包含字典的,将其注册为单例的,这意味着它将只被构造一次,然后被共享,并用于在控制器中使用它。那么,请向我解释如何在日志中生成第三行,因为它不是Post方法的一部分,它做的是长期运行的工作。在执行Post期间通过bbb路由?您启动Post。。它会运行一段时间。但在这段时间内,您发布到PostStatetaskId;当你这样做的时候,你希望字典计数仍然是1。但这不起作用,因为每个请求本质上都会再次初始化TaskDictionary。您放置在taskDictionary taskDictionary=新建taskDictionary中的此字段;请求之间显然不共享。您需要创建一个服务并对其进行DI,这样您就可以在不同的请求中共享它。您的日志记录由两个post请求生成。对吗?你是说每个请求都是控制器的全新实例,因此是全新的TaskDictionary?对。有2个职位。一个URI是mycontroller/aaa,另一个是mycontroller/bbb。也许你指的是这种方法。在这种情况下,谁会认为我在说在托管服务中运行后台任务?但我很感谢您的评论,并通过添加指向正确文档的链接改进了答案!:谢谢只是其中一个请求正在长时间运行。我不能超过215秒。
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.