我解释我的情况。
我有一个生产者1到N的消费者模式。我正在使用阻止收集,并且一切正常。做一些测试,我注意到了这种奇怪的行为:
我正在测试对数据的处理花费了我的消费者多长时间。我注意到了这些奇怪的事情,在下面,您会发现清除了我的操作的代码,这些代码会产生奇怪的行为。
我有1个生产者的4个消费者。对于大多数数据,控制台不打印任何内容,因为ts = 0(在刻度下),但是随机地(每1至5秒之间),它会绘制类似这样的内容(不是以这种非常特定的顺序,而是相同的种类) ):
10000
20001
10000
30002
10000
40003
10000
10000
它大约是10,000个滴答声,所以大约1毫秒。始终为(N)000(N-1)格式的数字。请注意,我消耗的BlockingCollection取决于完全在随机时间发生的某些网络事件的填充。这里没有常规。
时机几乎是完美的,始终是10,000刻度的倍数。
这可能是什么呢?ks!
while(IsAlive)
{
DataToFieldMapping item;
try
{
_CollectionToConsume.TryTake(out item, -1);
}
catch
{
item = null;
}
if (item != null)
{
long ts = (DateTime.Now.Ticks - item.TimeStamp.Ticks);
if(ts>10)
Console.WriteLine(ts);
}
}
这里发生的是DateTime.Now
精度相当有限。它没有给您时间到最近的滴答声。它仅每10,000滴答滴答更新一次,这就是为什么您通常在打印物中看到1万滴答滴答的倍数的原因。
如果你真的想获得这些事件的持续时间更好的手感,使用StopWatch
类,它有一个很大更高的精度。就是说,这StopWatch
仅仅是诊断工具(因此,它为什么在Diagnostics
名称空间中)。您应该只使用它来帮助您诊断正在发生的事情,并且应该在生产代码中使用它。
顺便说一句,这里实际上根本不需要使用计时器。看来您正在创建几个正在轮询BlockingCollection
新内容的使用者。没有理由这样做。他们可以简单地阻止,直到集合中有项目为止。(因此,名称BlockingCollection
。
最简单的方法是让消费者简单地执行此操作:
foreach(var item in _CollectionToConsume.GetConsumingEnumerable())
ProcessItem(item);
然后,只需在后台线程中运行该代码即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句