我有两个定时器在应用程序上工作。一种是在接收到新消息并将其添加到并发字典时触发。另一个是触发以从字典中删除任何消息(即,尝试获取消息),如果该消息在字典中存在'x‘时间。
public class Program
{
static void Main()
{
string val;
Console.Write("Enter Type: ");
val = Console.ReadLine();
int type = Convert.ToInt32(val);
TimerExample.Start(type);
}
}
static class TimerExample
{
static Timer _timer;
static Timer _timer2;
static ConcurrentDictionary<int, Message> dict;
static int _type;
public static void Start(int type)
{
var timer = new Timer(3000);
timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
timer.Enabled = true;
_timer = timer;
var timer2 = new Timer(3000);
timer2.Elapsed += new ElapsedEventHandler(_timer2_Elapsed);
timer2.Enabled = true;
_timer2 = timer2;
_type = type;
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_dict.Add(_type,DateTime.Now);
}
static void _timer2_Elapsed(object sender, ElapsedEventArgs e)
{
//remove here if type is stuck in the dict for more than 30 secs
}
}在一个时间点可以有多种类型作为字典中的键,所以每当第二个计时器过去时,我必须检查字典中每种类型的时间。如果一个或多个类型在字典中的时间超过30秒,请将它们从字典中删除。
我担心的是,每当我读字典的时候,第一个计时器也会为已经添加的类型添加新的时间,这会导致一致性问题吗?另一个问题是,每当我从dict获得消息时,任何类型的消息都在那里超过30秒,并且当时只有timer1也更新了该类型的新时间,这是否也会导致并发问题或数据丢失问题?
有什么帮助吗?
发布于 2019-05-30 21:42:04
根据你想要的评论
如果您在处理消息时管理重复的消息,而不是在接收消息时管理它们,这会更容易。
当消息传入时,将它们插入到ConcurrentQueue<Message>中,而不是字典中。在此步骤中,是否有重复项并不重要。
设置30秒的计时器。你只需要一个定时器。当计时器到期时,从队列中读取所有内容。目前还不清楚你是如何识别重复消息的,但这里就是你识别重复消息的地方。
例如,如果Message覆盖了Equals,则相同的消息是“相等的”,您可以使用Hashset。它是一个集合,如果添加的项已经在集合中,则忽略这些项。
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
var messagesFromQueue = DequeueUniqueMessages(messageQueue);
DoWhateverWithTheMessages(messagesFromQueue);
}
IEnumerable<Message> DequeueUniqueMessages(ConcurrentQueue<Message> messageQueue)
{
var result = new HashSet<Message>();
while (messageQueue.TryDequeue(out Message dequeued))
result.Add(dequeued);
return result;
}或者如果它没有或者不应该覆盖Equals,你可以定义一个自定义的IEqualityComparer并使用这个重载:
var result = new HashSet<Message>(new YourCustomMessageComparer());将您的ConcurrentQueue传递给该方法,您将得到一组消息。通过这种方式,它们是先入先出处理的,即使在从队列读取时仍在向队列中添加新消息,也不会出错。
https://stackoverflow.com/questions/56376962
复制相似问题