某些场景并发量太高,需要采用队列辅助,特此备注:多线程队列,先进先出
某些情况也会用到阻塞当前线程,等待服务器返回或者耗时的处理,这种情况,可采用信号量辅助
ManualResetEvent allDone = new ManualResetEvent(false);//初始化
allDone.Reset();//信号量重置,状态为阻塞
allDone.WaitOne(5*1000);//阻塞当前线程,最大等待5秒
allDone.Set();//释放信号量,将阻塞的线程继续向下
口水话注解:调用了Set方法将事件设为true后,不会去调用Reset方法,这将导致事件一直处于true,其它等待的多个线程都会得到执行,直到你手动调用Reset方法。
相当于你把门打开后,需要手动去关(非自动门)。
AutoResetEvent ReciveResetEvent = new System.Threading.AutoResetEvent(true);//初始化,未开启阻塞
ReciveResetEvent.WaitOne(30000);//阻塞
ReciveResetEvent.Set();//释放后,自动开启阻塞
口水话注解:调用了Set方法将事件设为true之后,其中一个等待线程得到执行后,它会自动调用Reset方法,将事件信号设为false,以阻塞其它的线程。
相当于放一个线程进来,门自动就关了(自动门)。
/*
例子:
//初始化后台处理消息线程
AsyncQueueDataProcessor<string> asyncQueueDetector = new AsyncQueueDataProcessor<string>();
asyncQueueDetector.ProcessData += AsyncQueue_ProcessData;//事件里处理有数据时
asyncQueueDetector.Start();
服务启动后,使用 asyncQueueDetector.AppendData 追加数据到队列
*/
/// <summary>
/// 异步处理队列数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class AsyncQueueDataProcessor<T> : IDisposable
{
#region 成员变量
/// <summary>
/// 待处理的数据队列
/// </summary>
ConcurrentQueue<T> DataQueue;
/// <summary>
/// 数据处理定时器
/// </summary>
Timer processTimer;
#endregion
#region 构造函数
/// <summary>
/// 初始化
/// </summary>
/// <param name="intervalMillSecond"></param>
public AsyncQueueDataProcessor(int intervalMillSecond = 120)
{
DataQueue = new ConcurrentQueue<T>();
processTimer = new Timer(intervalMillSecond);
processTimer.Elapsed += ProcessTimer_Elapsed;
processTimer.AutoReset = false;
}
#endregion
#region 自定义事件
/// <summary>
/// 数据抛出时触发
/// </summary>
public event EventHandler<T> ProcessData;
#endregion
#region 公共方法
/// <summary>
/// 释放所有资源
/// </summary>
public void Dispose()
{
processTimer.Dispose();
ClearData();
}
/// <summary>
/// 开始处理数据
/// </summary>
public void Start()
{
processTimer.Start();
}
/// <summary>
/// 停止处理数据
/// </summary>
public void Stop()
{
processTimer.Stop();
}
/// <summary>
/// 追加数据到队列
/// </summary>
/// <param name="data"></param>
public void AppendData(T data)
{
DataQueue.Enqueue(data);
}
/// <summary>
/// 清空队列数据
/// </summary>
public void ClearData()
{
do
{
} while (DataQueue.TryDequeue(out T t));
}
#endregion
#region 事件
//处理数据时执行
private void ProcessTimer_Elapsed(object sender, ElapsedEventArgs e)
{
T t;
if (DataQueue.TryDequeue(out t))
{
if (ProcessData != null)
{
try
{
ProcessData(this, t);
}
catch (Exception exp)
{
Debug.WriteLine($"队列里面发生了未处理的异常-{exp.Message}\r\n{exp.StackTrace}");
}
}
}
processTimer.Start();
}
#endregion
}