|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
|
|
namespace HybirdFrameworkDriver.Common;
|
|
|
|
|
|
|
|
|
|
public class MsgCache<T, TReq, TResp>
|
|
|
|
|
{
|
|
|
|
|
private readonly ConcurrentDictionary<string, MsgPair<TReq, TResp>> _dictionary = new();
|
|
|
|
|
private static readonly string MsgKey = "msg_";
|
|
|
|
|
|
|
|
|
|
public void Add(string key, dynamic value)
|
|
|
|
|
{
|
|
|
|
|
_dictionary[key] = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryGet(string key, out MsgPair<TReq, TResp>? value)
|
|
|
|
|
{
|
|
|
|
|
return _dictionary.TryGetValue(key, out value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Remove(string key)
|
|
|
|
|
{
|
|
|
|
|
_dictionary.Remove(key, out var value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddByMsgId(int key, MsgPair<TReq, TResp> value)
|
|
|
|
|
{
|
|
|
|
|
_dictionary[MsgKey + key] = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool TryGetMsgId(int key, out MsgPair<TReq, TResp>? value)
|
|
|
|
|
{
|
|
|
|
|
return _dictionary.TryGetValue(MsgKey + key, out value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveMsgId(int key)
|
|
|
|
|
{
|
|
|
|
|
_dictionary.Remove(MsgKey + key, out var value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class MsgPair<TReq, TResp>
|
|
|
|
|
{
|
|
|
|
|
private readonly ManualResetEvent _lock = new(false);
|
|
|
|
|
private TReq? _req;
|
|
|
|
|
|
|
|
|
|
public TReq? Req
|
|
|
|
|
{
|
|
|
|
|
get => _req;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_req = value;
|
|
|
|
|
ClearResp();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private TResp? _resp;
|
|
|
|
|
|
|
|
|
|
public void ClearResp()
|
|
|
|
|
{
|
|
|
|
|
_resp = default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetResp(TResp? resp)
|
|
|
|
|
{
|
|
|
|
|
_resp = resp;
|
|
|
|
|
_lock.Set();
|
|
|
|
|
_lock.Reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TResp? GetResp(TimeSpan? timeSpan = default)
|
|
|
|
|
{
|
|
|
|
|
if (timeSpan != null)
|
|
|
|
|
{
|
|
|
|
|
_lock.WaitOne(timeSpan.Value);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_lock.WaitOne();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _resp;
|
|
|
|
|
}
|
|
|
|
|
}
|