首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ManualResetEvent -积压的事件

ManualResetEvent -积压的事件
EN

Stack Overflow用户
提问于 2013-11-19 20:24:39
回答 2查看 78关注 0票数 0

我在ManualResetEvent和积压的事件中遇到了一些问题。我的应用程序正在订阅消息,然后运行一个很长的任务。

我的问题是,我收到的消息太多,我无法处理。任务大约需要5秒来处理,但我每2-3秒就会收到一条新消息。

理想情况下,我想要做的是忽略任何新事件,直到我完成任务处理,然后再次开始“侦听”。目前,我似乎正在按照接收和处理的顺序积压事件。正如您可以想象的那样,几个小时后,正在处理的消息非常旧。

我不能从多个线程运行长时间运行的任务。

也许我需要某种队列机制,然后清除最后一条消息(Last On First Off)并删除队列?

有什么想法吗?

我还会在长时间运行的进程结束时调用ManualResetEvent.Set() --根据我的研究,这是正确的吗?我是否应该在长时间运行的任务开始时重置(),使线程阻塞,然后在结束时设置()?

EN

回答 2

Stack Overflow用户

发布于 2013-11-20 00:10:58

创建一个循环缓冲区,将其视为后进先出队列(堆栈)。因此,假设您希望队列中最多有10个条目:

代码语言:javascript
复制
const int MaxItems = 10;
Item[] theQueue = new Item[];
int insertPoint = 0;
object myLock = new object();
// initialize the array to all NULL.

void Enqueue(Item t)
{
    lock (myLock)
    {
        theQueue[insertPoint] = t;
        insertPoint = (insertPoint+1) % 10;
    }
}

Item Dequeue()
{
    lock (myLock)
    {
        int takeFrom = insertPoint-1;
        if (takeFrom < 0)
            takeFrom = MaxItems-1;
        if (theQueue[takeFrom] != null)
        {
            var rslt = theQueue[takeFrom];
            insertPoint = takeFrom;
            return rslt;
        }
        // queue is empty. Either return null or throw an exception.
        return null;
    }
}

当然,您会希望将所有这些都包装到一个漂亮的对象中。但这是基本的想法。

票数 1
EN

Stack Overflow用户

发布于 2013-11-19 22:41:14

这个怎么样:

在任何给定时间,您都有一条消息正在处理,还有一条消息在等待处理。

当您收到新消息时,您将覆盖等待处理的消息。

您的处理线程将等待,直到有消息等待处理,然后将其标记为正在处理,处理它,然后再次启动。

添加一些同步逻辑,您将获得以下代码:

代码语言:javascript
复制
private object _sync = new object();
private Message _beingProcessed;
private Message _waitingToBeProcesssed;

public void OnMessageReceived(Message message)
{
    lock(sync)
    {
        _waitingToBeProcesssed = message;
        Monitor.Pulse(sync);
    }
}

public void DoWork()
{
    while (true)
    {
        lock (sync)
        {
            while (_waitingToBeProcesssed == null)
            {
                Monitor.Wait(sync);
            }

            _beingProcessed = _waitingToBeProcesssed;
            _waitingToBeProcesssed = null;
        }

        Process(_beingProcessed); //Do the actual work
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20071506

复制
相关文章

相似问题

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