Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#.NET-带计时器的缓冲消息_C#_.net_Linq_Timer_Buffering - Fatal编程技术网

C#.NET-带计时器的缓冲消息

C#.NET-带计时器的缓冲消息,c#,.net,linq,timer,buffering,C#,.net,Linq,Timer,Buffering,我需要实现一个消息缓冲系统,它也是基于时间的 我需要做的是存储我的类的实例,然后在我达到100个实例或1分钟后转发它们 基本上: List<Message> messages; public void GotNewMessage(Message msg) { messages.add(msg); if (messages.count() == 100 || timer.elapsed(1 minute)) { SendMessages(me

我需要实现一个消息缓冲系统,它也是基于时间的

我需要做的是存储我的类的实例,然后在我达到100个实例或1分钟后转发它们

基本上:

List<Message> messages;

public void GotNewMessage(Message msg)
{
    messages.add(msg);

    if (messages.count() == 100 || timer.elapsed(1 minute))
    {
        SendMessages(messages);
        messages.clear()
    }
}
列出消息;
public void GotNewMessage(Message msg)
{
添加消息(msg);
if(messages.count()==100 | |计时器已过(1分钟))
{
发送消息(消息);
messages.clear()
}
}

我似乎不知道如何在不过度使用锁的情况下实现这一点,锁的使用会大大降低进程的速度。有谁知道实施这样一个系统的好方法吗?谢谢。

< P>首先,你应该考虑使用<强>并发队列> /Sistar的<强>列表< /强>。strong>ConcurrentQueue始终是线程安全的,不需要额外的锁。这样,您已经为消息队列保留了一个锁。 联锁在不可用时提供原子性

根据,独立的读/写是原子的(但仅对某些数据类型而言,long并不总是原子的-这就是为什么我移动了
DateTime。现在。勾选
,以获得int32而不丢失任何会影响所用时间的位),读修改写(例如++I)永远不是原子的


移位(例如<强> > p>首先,您应该考虑使用<强>并发队列> /Sistar的<强>列表。<强>并发队列是线程安全的,不需要额外的锁。 联锁在不可用时提供原子性

根据,独立的读/写是原子的(但仅对某些数据类型而言,long并不总是原子的-这就是为什么我移动了
DateTime。现在。勾选
,以获得int32而不丢失任何会影响所用时间的位),读修改写(例如++I)永远不是原子的


转换(例如,对于此类需求(将时间与顺序结合起来),有一个奇妙的库,它是反应式扩展。请参阅

然后你就可以写这样的东西

void Main()
{
    messages
        .Buffer(TimeSpan.FromMinutes(1), 100) // Buffer until 100 items or 1 minute has elapsed, whatever comes first.
        .Subscribe(msgs => SendMessages(msgs));     
}

Subject<Message> messages = new Subject<Message>();

public void GotNewMessage(Message msg)
{
    messages.OnNext(msg);
}
void Main()
{
信息
.Buffer(TimeSpan.FromMinutes(1),100)//缓冲到100个项目或1分钟后,无论先到什么。
。订阅(msgs=>SendMessages(msgs));
}
主题消息=新主题();
public void GotNewMessage(Message msg)
{
messages.OnNext(msg);
}
注意:这还没有准备好生产,但它展示了如何进行生产的基本方法。根据您从何处获取消息,有更好的方法来创建可观察对象以供订阅

更多参考资料:


如果您的信息是通过事件接收的,您可以将事件链接到RX流,请参阅和

对于此类需求(将时间与序列结合起来),有一个很棒的库,它是反应式扩展。请参阅

然后你就可以写这样的东西

void Main()
{
    messages
        .Buffer(TimeSpan.FromMinutes(1), 100) // Buffer until 100 items or 1 minute has elapsed, whatever comes first.
        .Subscribe(msgs => SendMessages(msgs));     
}

Subject<Message> messages = new Subject<Message>();

public void GotNewMessage(Message msg)
{
    messages.OnNext(msg);
}
void Main()
{
信息
.Buffer(TimeSpan.FromMinutes(1),100)//缓冲到100个项目或1分钟后,无论先到什么。
。订阅(msgs=>SendMessages(msgs));
}
主题消息=新主题();
public void GotNewMessage(Message msg)
{
messages.OnNext(msg);
}
注意:这还没有准备好生产,但它展示了如何进行生产的基本方法。根据您从何处获取消息,有更好的方法来创建可观察对象以供订阅

更多参考资料:


如果您的消息是使用事件接收的,您可以将事件链接到RX流,请参见和

您必须自己实现吗?有一个完整的库来完成这类事情。在伪实现中,如果有东西在两分钟内没有进入,您将失去一分钟的行为。您必须在方法外部保持计时器从事件处理程序wrt timer调用它。你必须自己实现吗?有一个完整的库来做这类事情。在你的伪实现中,如果有东西在两分钟内没有出现,你将失去一分钟的行为。你必须将计时器放在方法的外部,并从事件处理程序wrt timer.Excel调用它出借答案,不知道这个图书馆的存在。非常有用。谢谢!非常好的答案,不知道这个图书馆的存在。非常有用。谢谢!