ASP.NET Core 3.1 MVC多线程存邮件报COM Interop不支持错误如何解决
错误原因
- 直接报错根因:你代码中
thread.SetApartmentState(ApartmentState.MTA)这行调用了Windows平台专属的COM相关API,你发布的服务器是Linux系统(报错路径/opt可佐证),非Windows平台不支持COM Interop,所以抛出PlatformNotSupportedException。本地Windows环境运行正常是因为Windows原生支持该API。
解决方案
1. 直接修复报错
删除thread.SetApartmentState(ApartmentState.MTA);这行代码即可,.NET Core 3.1的线程默认就是MTA模式,无需手动设置。
2. 修复其他并发/逻辑隐患
你的代码还存在多个可引发后续异常的问题,建议同步修改:
线程安全问题
- 多线程直接修改
threadCount、processCount、savedMails三个共享变量,没有加锁会出现计数不准、集合写入异常:- 计数操作改用
Interlocked.Increment、Interlocked.Decrement原子操作 savedMails改用线程安全的ConcurrentBag<IncomingMailDto>存储
- 计数操作改用
线程管理问题
- 手动new Thread创建50个线程资源开销极高,建议改用
Parallel.ForEach,通过MaxDegreeOfParallelism参数控制并发数,代码更简洁性能更好。
ABP Session访问问题
- 不要在子线程中直接访问
AbpSession.TenantId、AbpSession.UserId,ABP Session默认和请求上下文绑定,子线程可能丢失上下文引发空引用。建议在遍历邮件前先把当前的TenantId、UserId取值存在本地变量,闭包传递给子线程使用。
SQL注入风险
- 你当前的
SqlQueryString类是直接拼接SQL字符串,存在严重的SQL注入风险,同时特殊字符会导致SQL执行失败。建议全部改用Dapper的参数化查询,不要手动拼接SQL条件。
Dapper封装优化
- 你的DapperOrm类不需要每次手动传入
new SqlConnection(),可以直接在构造函数内部创建连接,简化调用代码:
public DapperOrm(string connectionString = null) { SqlConnection = new SqlConnection(connectionString ?? ConnectionString); }
内容的提问来源于stack exchange,提问作者Ahmet atasagun
相关产品推荐
相关产品推荐

