一、需求
现在在写 API接口供其他项目调用,当该接口发生异常时,将会将错误信息发送到指定的邮箱中;
存在一个问题,当该接口发生异常,且其他程序使用for循环调用该接口,将会产生大量且重复的邮件信息;
现在想要对该种情况做出优化,当发送异常时,将会延迟10分钟再去发送,这期间所有的错误消息将会积累到一个set集合中
二、 核心代码
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Text;
namespace muti_req_api.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
// 注意,这里的变量要使用 static 修饰,保证全局唯一
private static bool isFirst = true;
private static Dictionary<string,HashSet<string>> dic = new Dictionary<string, HashSet<string>>();
[HttpGet()]
public object Get(string orderNumber,string message)
{
Console.WriteLine($"控制台输入orderNumber: {orderNumber},message: {message}");
// 延迟执行时间,这里自定义
int delayTime = 1000 * 20;
string key = orderNumber;
// 由于 10 分钟内,可能存在对同一个订单调用多次接口
// 且 message 的值可能重复也可能不重复,这里做去重操作
HashSet<string> value;
if (dic.TryGetValue(key,out value))
{
Console.WriteLine($"存在key {key},追加新值{message}");
value.Add(message);
}
else
{
Console.WriteLine($"不存在key {key},新建set集合,初始化值为{message}");
value = new HashSet<string> {message };
}
dic[key] = value;
// 如果是第一次进入或倒计时结束后访问,则开始倒计时 10 分钟,
// 到时间后,将会将这10分钟内容发送到指定的邮箱中
if (isFirst)
{
// 如果在10 分钟内,其他请求来访问,获取的都是false
isFirst = false;
var task = Task.Run(async delegate
{
await Task.Delay(delayTime);
// 这里用控制台输出模拟来模拟发送邮件
foreach (KeyValuePair<string, HashSet<string>> kvp in dic)
{
Console.WriteLine("----------------------------");
Console.WriteLine("Order number: " + kvp.Key);
StringBuilder setMessage = new StringBuilder();
foreach (var item in kvp.Value)
{
setMessage.Append(item + ";");
}
Console.WriteLine("Error message: " + setMessage.ToString());
}
// 初始化设置
isFirst = true;
dic = new Dictionary<string, HashSet<string>>();
});
}
return null;
}
}
}
三、演示案例
控制台输出如下:
控制台输入orderNumber: 000000000001,message: 111
不存在key 000000000001,新建set集合,初始化值为111
控制台输入orderNumber: 000000000001,message: 222
存在key 000000000001,追加新值222
控制台输入orderNumber: 000000000001,message: 333
存在key 000000000001,追加新值333
控制台输入orderNumber: 000000000001,message: 111
存在key 000000000001,追加新值111
控制台输入orderNumber: 000000000002,message: 111
不存在key 000000000002,新建set集合,初始化值为111
控制台输入orderNumber: 000000000002,message: 222
存在key 000000000002,追加新值222
控制台输入orderNumber: 000000000002,message: 333
存在key 000000000002,追加新值333
----------------------------
Order number: 000000000001
Error message: 111;222;333;
----------------------------
Order number: 000000000002
Error message: 111;222;333;
四、 参考
C# 集合(Collection) | 菜鸟教程 (runoob.com)
Dictionary<TKey,TValue>.TryGetValue(TKey, TValue) 方法 (System.Collections.Generic) | Microsoft Learn