【问题标题】:use GraphServiceClient from multiple threads (parallel) - send mails从多个线程(并行)使用 GraphServiceClient - 发送邮件
【发布时间】:2019-04-12 14:12:13
【问题描述】:

我需要使用 Windows 服务中的 Microsoft Graph 发送多封电子邮件。
我正在使用Microsoft.Graph NuGet 包。
我正在创建GraphServiceClient 并像这样发送邮件:

IGraphServiceClient graphClient = new GraphServiceClient("https://graph.microsoft.com/v1.0", authenticationProvider);
var email = new Message
{
    Body = new ItemBody
    {
        Content = "Works fine!",
        ContentType = BodyType.Html,
    },
    Subject = "Test",
    ToRecipients = recipientList
};

await graphClient.Users["test@example.onmicrosoft.com"].SendMail(email, true).Request().WithMaxRetry(5).PostAsync();

当我逐一发送电子邮件时:

for (var j = 0; j < 20; j++)
{
    await graphClient.Users["test@example.onmicrosoft.com"].SendMail(email, true).Request().WithMaxRetry(5).PostAsync();
    progressBar1.PerformStep();
}

一切正常,但是当我使用Parallel.For:

var res = Parallel.For(0, 20, async (i, state) =>
{
    var email = new Message
    {
        Body = new ItemBody
        {
            Content = "Works fine!",
            ContentType = BodyType.Html,
        },
        Subject = "Test",
        ToRecipients = recipientList
    };

    await graphClient.Users["test@example.onmicrosoft.com"].SendMail(email, true).Request().WithMaxRetry(5).PostAsync();
});

我收到错误,因为我收到了太多请求 (429),然后是不支持的媒体类型 (415)。

这是错误代码:

代码:RequestBodyRead 消息:缺少或为空的内容类型标头 尝试阅读消息时发现。内容类型标头是 必填。

这是它在 Fiddler 中的样子:

我的问题是:我可以使用 Graph 以及如何使用 Parallel.For 来避免此类错误。我已经为每个请求设置了WithMaxRetry(5)

我知道使用限制,但我认为WithMaxRetry(5) 会有所帮助。

【问题讨论】:

标签: c# .net microsoft-graph-api microsoft-graph-sdks microsoft-graph-mail


【解决方案1】:

您看到此内容的原因是缺少内容类型标头。当我们克隆 httprequestmessage 时,它​​并没有被克隆。这是fixed,将在客户端的下一个版本中。关于并行线程,我们计划实现基于资源的共享重试队列,以便我们在针对相同资源(和相同限制策略)的多个请求中使用单一重试方案。

【讨论】:

  • 期待下一个版本 :) 共享重试队列将是一个很棒的功能,尤其是当我们想要并行发送请求时。理想情况下,应该添加一个展示最佳实践的示例,以展示如何执行并行请求以及如何对它们进行批处理。
【解决方案2】:

它与线程无关。它与throtteling a.k.a 有关。您只能在特定时间段内执行 x 数量的请求。

dotnet graph api 客户端不支持批处理(很遗憾)。但是batching 你自己的这些请求很容易实现。一个请求可以发送 15 封邮件。

【讨论】:

  • 这是正确的,但 Exchange 的限制是每个邮箱的 10 个请求。因此,您需要以 10 个为一组进行批处理,而不是 15 个。即便如此,您的代码也需要考虑潜在的限制。您可能因多种原因受到限制,包括整体租户负载。
  • @Stephan, @Marc 我知道节流,但这就是 WithMaxRetry 的用途 (github.com/microsoftgraph/msgraph-sdk-dotnet/blob/…)。我假设此方法将在节流的情况下处理重试。奇怪的是我得到了429,但后来开始得到415
猜你喜欢
  • 2022-10-05
  • 2021-09-19
  • 2011-03-20
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 2019-06-16
  • 1970-01-01
相关资源
最近更新 更多