【发布时间】:2021-07-31 05:37:52
【问题描述】:
我有一个关于 Azure Functions 中并发运行任务的使用情况的问题,关于消费计划。
我们应用程序的一部分允许用户连接他们的邮件帐户,然后每 15 分钟下载一次邮件。我们有 azure 功能可以做到这一点,所有用户都可以使用。问题是,随着用户数量的增加,函数需要更多的时间来执行。
为了缓解超时情况,我更改了函数逻辑。您可以在下面找到一些代码。现在它为每个用户创建一个单独的任务,然后等待所有用户完成。还实现了一些异常处理,但这不是今天的主题。
问题是,当我检查一些日志时,我看到执行是因为函数不是同时执行的,而是一个接一个地执行。现在我想知道我的代码是否有错误,或者是天蓝色函数无法在这种情况下运行(我在 Microsoft 网站上没有找到任何建议,实际上恰恰相反)
PS - 我确实知道持久功能,但是出于某种原因,我想在没有它们的情况下解决这个问题。
我的代码:
List<Task<List<MailMessage>>> tasks = new List<Task<List<MailMessage>>>();
foreach (var account in accounts)
{
using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(6)))
{
try
{
tasks.Add(GetMailsForUser(account, cancellationTokenSource.Token, log));
}
catch (TaskCanceledException)
{
log.LogInformation("Task was cancelled");
}
}
}
try
{
await Task.WhenAll(tasks.ToArray());
}
catch(AggregateException aex)
{
aex.Handle(ex =>
{
TaskCanceledException tcex = ex as TaskCanceledException;
if (tcex != null)
{
log.LogInformation("Handling cancellation of task {0}", tcex.Task.Id);
return true;
}
return false;
});
}
log.LogInformation($"Zakończono pobieranie wiadomości.");
private async Task<List<MailMessage>> GetMailsForUser(MailAccount account, CancellationToken cancellationToken, ILogger log)
{
log.LogInformation($"[{account.UserID}] Rozpoczęto pobieranie danych dla konta {account.EmailAddress}");
IEnumerable<MailMessage> mails;
try
{
using (var client = _mailClientFactory.GetIncomingMailClient(account))
{
mails = client.GetNewest(false);
}
log.LogInformation($"[{account.UserID}] Pobrano {mails.Count()} wiadomości dla konta {account.EmailAddress}.");
return mails.ToList();
}
catch (Exception ex)
{
log.LogWarning($"[{account.UserID}] Nie udało się pobrać wiadomości dla konta {account.EmailAddress}");
log.LogError($"[{account.UserID}] {ex.Message} {ex.StackTrace}");
return new List<MailMessage>();
}
}
输出:
【问题讨论】:
-
我猜 _mailClientFactory.GetIncomingMailClient 正在返回同一个邮件客户端,它要么有一个锁,要么你的邮件服务器每个连接只允许 1 个请求(啊,只有一个连接)
-
更有趣的是,我还有3个用这样的逻辑重做的函数,似乎都面临这个问题。
-
所以问题可能不在于您发布的代码:-(
-
实际上,虽然 GetMailsForUser 有
async修饰符,但我看不到任何async函数或任何awaits。这只是一个 C+P 错误,还是正确的? -
但是你的代码都不是异步的!仅返回一个任务并不会使其异步。
标签: c# azure asp.net-core azure-functions