首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在并发字典c#上工作的两个计时器

在并发字典c#上工作的两个计时器
EN

Stack Overflow用户
提问于 2019-05-30 19:00:07
回答 1查看 199关注 0票数 0

我有两个定时器在应用程序上工作。一种是在接收到新消息并将其添加到并发字典时触发。另一个是触发以从字典中删除任何消息(即,尝试获取消息),如果该消息在字典中存在'x‘时间。

代码语言:javascript
复制
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也更新了该类型的新时间,这是否也会导致并发问题或数据丢失问题?

有什么帮助吗?

EN

回答 1

Stack Overflow用户

发布于 2019-05-30 21:42:04

根据你想要的评论

  • 以固定的时间间隔处理消息-在处理消息之前收集消息30秒。
  • 当该时间间隔过去时,您可能已经收到相同的消息两次,但您只想处理它一次。

如果您在处理消息时管理重复的消息,而不是在接收消息时管理它们,这会更容易。

当消息传入时,将它们插入到ConcurrentQueue<Message>中,而不是字典中。在此步骤中,是否有重复项并不重要。

设置30秒的计时器。你只需要一个定时器。当计时器到期时,从队列中读取所有内容。目前还不清楚你是如何识别重复消息的,但这里就是你识别重复消息的地方。

例如,如果Message覆盖了Equals,则相同的消息是“相等的”,您可以使用Hashset。它是一个集合,如果添加的项已经在集合中,则忽略这些项。

代码语言:javascript
复制
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并使用这个重载:

代码语言:javascript
复制
var result = new HashSet<Message>(new YourCustomMessageComparer());

将您的ConcurrentQueue传递给该方法,您将得到一组消息。通过这种方式,它们是先入先出处理的,即使在从队列读取时仍在向队列中添加新消息,也不会出错。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56376962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档