带CancellationToken的循环中OnSendEmail重复调用致多次错误弹窗的解决需求
解决方案:避免重复发送错误通知并停止调用失败的Email服务
核心思路
通过添加状态标记跟踪Email服务的失败状态,确保仅发送一次错误通知,且后续不再执行Email发送逻辑。
修改后的代码实现
1. 添加状态标记字段
在类中新增一个私有字段,用于记录Email服务是否已失败:
// 标记Email服务是否已失败,避免重复处理和通知 private bool _emailServiceFailed = false;
2. 更新OnSendEmail方法
修改方法逻辑,确保仅在第一次失败时发送通知,并更新失败状态:
private void OnSendEmail(string message) { // 若服务已失败,直接返回,不再尝试发送 if (_emailServiceFailed) return; try { EmailService.SendEmail(message); } catch (Exception ex) { // 仅发送一次错误通知到UI this.publisherSocket.SendMultipartMessage(ex.Message); // 标记服务已失败,后续不再处理Email请求 _emailServiceFailed = true; } }
3. 调整MessagesAsync循环逻辑
在处理Email类型消息前检查失败状态,跳过已失效的服务处理:
private Task MessagesAsync(CancellationToken cancelToken) => Task.Run(() => { while (!cancelToken.IsCancellationRequested) { var message = this.routerSocket.ReceiveMultipartMessage(); if (message is null) continue; switch (MessageType) { case Email: // 仅当Email服务未失败时执行发送逻辑 if (!_emailServiceFailed) { OnSendEmail(message); } else { // 可选:回复SignalOK避免发送端阻塞,或发送服务暂停通知 this.routerSocket.SignalOK(); } break; case SMS: OnSendSMS(message); break; // 其他分支保持原有逻辑 default: this.routerSocket.SignalOK(); break; } } }, cancelToken);
关键改动说明
- 状态标记:
_emailServiceFailed作为开关,彻底阻断后续的Email发送尝试 - 前置检查:OnSendEmail方法开头先判断状态,减少无效操作
- 单次通知:异常捕获后仅发送一次错误信息,立即标记服务失败
- 循环分支优化:已失败的Email请求直接跳过处理,避免重复触发错误
内容的提问来源于stack exchange,提问作者SuryaKavitha
相关产品推荐
相关产品推荐

