C# Azure函数中的ConcurrentQueue出列问题

C# Azure函数中的ConcurrentQueue出列问题,c#,azure-functions,concurrent-queue,C#,Azure Functions,Concurrent Queue,我已经声明了一个ConcurrentQueue并添加了一个GUID列表。添加到队列是可以的,但是当我从TimerTrigger函数内部访问队列时,它似乎是空的updateQueue.count为0。这种行为是在云中发生的,但当我在本地执行相同的操作时,效果很好 public static class Function1 { private static readonly ConcurrentQueue<IEnumerable<Guid>> updateQueue

我已经声明了一个ConcurrentQueue并添加了一个GUID列表。添加到队列是可以的,但是当我从TimerTrigger函数内部访问队列时,它似乎是空的updateQueue.count为0。这种行为是在云中发生的,但当我在本地执行相同的操作时,效果很好

public static class Function1
{
    private static readonly ConcurrentQueue<IEnumerable<Guid>> updateQueue = new ConcurrentQueue<IEnumerable<Guid>>();

    public static async Task<IActionResult> UpdateRun(
        [HttpTrigger(AuthorizationLevel.Admin, "post", Route = null)] HttpRequest req, ExecutionContext execContext)
    {
        logger.LogInformation($"FunctionUpdate Start");
        using var reader = new StreamReader(req.Body);
        var request = JsonConvert.DeserializeObject<IEnumerable<Request>>(reader.ReadToEnd());
        var correlationIds = request?.Select(s => s.CorrelationId);

        updateQueue.Enqueue(correlationIds);
        return new OkObjectResult(new Response { HttpStatusCode = HttpStatusCode.Accepted });
    }

    [FunctionName("FunctionHandleQueue"), Timeout("00:05:00")]
    public static async Task HandleQueue([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, ExecutionContext execContext) // once every 1 minutes
    {
        logger.LogInformation($"before updateQueue condition : {updateQueue.Count}"); 
        if (updateQueue.Count > 0)
        {
            logger.LogInformation($"after updateQueue condition {updateQueue.Count}");

            var guids = new List<Guid>();
            var count = 0;
            while (count <= 1000 && updateQueue.Count > 0)
            {
                updateQueue.TryDequeue(out var updateRequest);
                var enumerable = updateRequest.ToList();
                count += enumerable.Count;
                guids.AddRange(enumerable);
            }

            await new ProcessUpdateSales(CreateMapper(), execContext)
                .Orchestrate(guids)
        }
    }
}
当TimerTrigger每1分钟执行一次时,会创建日志:

updateQueue之前的条件:0


为什么updateQueue.Count总是0?我做错了什么?

虽然Azure功能通常共享一个背板,但不能保证。资源可以随时向下或向上旋转,函数的新副本可能无法访问原始状态。因此,如果使用静态字段跨函数执行共享数据,则应该能够从外部源重新加载数据

这就是说,这也不一定是可取的,因为Azure函数是如何被设计来使用的。Azure功能通过动态可伸缩性实现高吞吐量。由于处理当前工作负载需要更多的资源,因此可以自动调配这些资源以保持高吞吐量

因此,在单个函数执行中执行过多的工作实际上会干扰整个系统的吞吐量,因为函数背板无法提供额外的工作人员来处理负载


如果需要保存状态,请使用一种永久存储形式。这可以采取Azure持久功能、Azure存储队列、Azure服务总线队列甚至数据库的形式。此外,为了最好地利用函数的可伸缩性,请尝试将工作负载减少到可管理的批处理中,以允许进行大量并行处理。虽然您可能需要在单个操作中前置工作,但您希望后续处理尽可能更加精细。

虽然Azure功能通常共享一个背板,但这并不能保证。资源可以随时向下或向上旋转,函数的新副本可能无法访问原始状态。如果您需要保留状态,请使用持久函数或实际队列,如Azure存储队列。添加到David的注释:它在您的计算机上本地工作,因为只有一个本地应用程序域由函数的开发运行时旋转,所以您可以从同一队列对象添加和删除。谢谢David&Roman。所以你们的意思是,当TimerTrigger函数尝试访问时,即使updateQueue只是特定于单个函数,updateQueue也不能保证可用?正确。代码中的单个函数并不是单个运行时函数所能做到的:。@HuryShen当然可以,很乐意!补充。