从多个线程(并行)使用 GraphServiceClient - 发送邮件

use GraphServiceClient from multiple threads (parallel) - send mails

我需要使用 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)。

这是错误代码:

Code: RequestBodyRead Message: A missing or empty content type header was found when trying to read a message. The content type header is required.

这是它在 Fiddler 中的样子:

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

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

跟线程没关系。它与 throtteling a.k.a 有关。您在特定时间段内只能执行 x 次请求。

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

你之所以看到这个是因为缺少内容类型 header。当我们克隆 httprequest 消息时,它没有被克隆。这已 fixed 并将在客户端的下一个版本中。关于并行线程,我们计划实施基于资源的共享重试 queue,以便我们在针对相同资源(和相同的限制策略)的多个请求中使用单一重试方案。