gpt4 book ai didi

c# - BlockingCollection——高同步问题

转载 作者:行者123 更新时间:2023-11-30 19:48:33 33 4
gpt4 key购买 nike

将来自多个线程的消息放到一个队列中并让一个单独的线程一次处理一个队列中的项目的最佳方法是什么?

在尝试断开多个线程的事件时,我经常使用这种模式。

我正在为此使用 BlockingCollection,如下面的代码摘录所示:

// start this task in a static constructor
Task.Factory.StartNew(() => ProcessMultiUseQueueEntries(), TaskCreationOptions.LongRunning);


private static BlockingCollection<Tuple<XClientMsgExt, BOInfo, string, BOStatus>> _q = new BlockingCollection<Tuple<XClientMsgExt, BOInfo, string, BOStatus>>();

/// <summary>
/// queued - Simple mechanism that will log the fact that this user is sending an xMsg (FROM a user)
/// </summary>
public static void LogXMsgFromUser(XClientMsgExt xMsg)
{
_q.Add(new Tuple<XClientMsgExt, BOInfo, string, BOStatus>(xMsg, null, "", BOStatus.Ignore));
}

/// <summary>
/// queued - Simple mechanism that will log the data being executed by this user
/// </summary>
public static void LogBOToUser(BOInfo boInfo)
{
_q.Add(new Tuple<XClientMsgExt, BOInfo, string, BOStatus>(null, boInfo, "", BOStatus.Ignore));
}

/// <summary>
/// queued - Simple mechanism that will log the status of the BO being executed by this user (causes the red square to flash)
/// </summary>
public static void LogBOStatus(string UserID, BOStatus status)
{
_q.Add(new Tuple<XClientMsgExt, BOInfo, string, BOStatus>(null, null, UserID, status));
}

/// <summary>
/// An endless thread that will keep checking the Queue for new entrants.
/// NOTE - no error handling since this can't fail... :) lol etc
/// </summary>
private static void ProcessMultiUseQueueEntries()
{
while (true) // eternal loop
{
Tuple<XClientMsgExt, BOInfo, string, BOStatus> tuple = _q.Take();

// Do stuff

}
}

这工作正常 - 所以我认为 - 直到 VS2010 中的性能向导开始突出显示 _q.Take() 行作为我代码中最高的争用行!

请注意,我还使用了标准的 ConcurrentQueue 和 ManualResetEvent 组合,每次我将一个项目插入队列时,我都会发出重置事件信号,允许工作线程检查和处理队列,但这也具有相同的净效果,即被突出显示在 .WaitOne() 方法上...

是否有其他方法可以解决这种让许多线程将对象添加到并发队列的常见模式 - 并让一个线程在自己的时间一次一个地处理项目...

谢谢!!

最佳答案

最高争用线?是的,因为它是一个阻塞集合!该调用将阻塞(例如,它可能正在等待 WaitHandle),直到另一个元素被添加到集合中。

你确定这是一个问题吗?这听起来正是我所期望的。

如果不清楚我的意思,请考虑以下代码:

var blocker = new BlockingCollection<int>();
int nextItem = blocker.Take();

您希望 Take 持续多长时间?调用上面运行?我预计它会永远等待,因为没有任何内容被添加到 blocker .因此,如果我分析上述代码的“性能”,我会看到 Take就在长时间运行的方法列表的顶部。但这并不表示有问题;再次强调:您希望阻止该调用。


在一个完全独立的注释中,我可能会建议替换 Tuple<XClientMsgExt, BOInfo, string, BOStatus>使用其属性具有描述性名称的类型? (当然,这个建议与你的问题无关;这只是一个一般性的建议。)

关于c# - BlockingCollection——高同步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5356003/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com