从多个线程(并行)使用 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,以便我们在针对相同资源(和相同的限制策略)的多个请求中使用单一重试方案。
我需要使用 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,以便我们在针对相同资源(和相同的限制策略)的多个请求中使用单一重试方案。