【发布时间】:2021-01-15 20:51:10
【问题描述】:
我已经声明了一个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 分钟执行一次时会创建日志:
更新队列之前条件:0
为什么updateQueue.Count 总是 0?我做错了什么?
【问题讨论】:
-
虽然 Azure Functions 可能通常共享一个背板,但不能保证。资源可以随时停止或启动,功能的新副本可能无法访问原始状态。如果需要保留状态,请使用持久函数或实际队列,例如 Azure 存储队列。
-
补充大卫的评论:它在您的机器上本地工作,因为只有一个本地应用程序域由函数的开发运行时启动,因此您可以从同一个队列对象中添加和删除。
-
谢谢大卫和罗曼。所以你的意思是即使 updateQueue 仅特定于单个函数,但当 TimerTrigger 函数尝试访问时,不能保证 updateQueue 可用?
-
正确。代码中的单个函数不会生成单个运行时函数:)。
-
@HuryShen 确定,很高兴!已添加。
标签: c# azure-functions concurrent-queue