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

时间:2019-04-12 14:12:13

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

我需要使用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中的外观:

enter image description here

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

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

2 个答案:

答案 0 :(得分:1)

这与线程无关。这与throtteling亦称a.k.a.在一个特定的时间段内您只能进行x个请求。

dotnet图形api客户端不支持批处理(足够糟糕)。但是batching自己可以轻松实现这些请求。这样一来,您就可以发送15封邮件。

答案 1 :(得分:1)

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