You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SendEmailAsync与Parallel.ForEach遇问题,咨询其并行可用性

SendEmailAsync能否用于并行方法?

SendEmailAsync本身完全支持异步并行执行,但你当前的用法存在问题,这才导致控制台程序无响应。

问题根源

Parallel.ForEach是为CPU密集型的同步任务设计的,它不兼容异步委托。你传入的async item => ...会被当作async void方法处理:

  • async void的异常无法被常规方式捕获,可能导致程序悄悄崩溃;
  • Parallel.ForEach不会等待异步操作完成,主线程会直接继续执行,控制台程序的主线程如果没等待所有异步发邮件任务结束,就会直接退出,表现为“停止运行且无响应”。

正确的异步并行写法

处理发邮件这类I/O密集型异步任务,应该用Task.WhenAll结合异步遍历:

// 遍历所有记录,创建异步任务
var emailTasks = registros.Select(async item =>
{
    // ... 这里写你的前置逻辑,比如构造myMessage
    var response = await client.SendEmailAsync(myMessage).ConfigureAwait(false);
});

// 等待所有异步邮件任务完成
await Task.WhenAll(emailTasks);

额外注意事项

  • 邮件服务商通常有并发发送限制,并行数量过多可能被限流、封禁IP,建议根据服务商规则控制并发数。
  • 如需手动控制并发量,可以用SemaphoreSlim实现限流:
// 限制同时最多5个并发任务
var semaphore = new SemaphoreSlim(5);

var emailTasks = registros.Select(async item =>
{
    await semaphore.WaitAsync().ConfigureAwait(false);
    try
    {
        // ... 构造邮件、发送逻辑
        var response = await client.SendEmailAsync(myMessage).ConfigureAwait(false);
    }
    finally
    {
        // 释放信号量,允许下一个任务执行
        semaphore.Release();
    }
});

await Task.WhenAll(emailTasks);

内容的提问来源于stack exchange,提问作者David Programer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:32:36