ConcurrentQueue <strongbox <t>&gt; </strongbox <t>的用法

时间:2012-11-28 18:37:23

标签: c# concurrent-collections

我基本上是在寻找从线程中的摄像头获取的图像集合的容器。由于ConcurrentQueue是线程安全的,我想使用它。但在调试我的代码时,我发现this article

  

如果元素很小,你可能永远不会注意到这一点。如果,   然而,元素保留了大量资源(例如,每个元素都是   一个巨大的图像位图),你可以看到它的影响   (一种解决方法是对包装器对象进行排队,例如有一个   ConcurrentQueue<StrongBox<T>>而不是ConcurrentQueue<T>   在包装器具有之后,将包装器对T值的引用置零   已经出局了。)

据我所知,StrongBox是原始价值的一种包装。这是否意味着我必须存储另一组图像?

所以我正在寻找ConcurrentQueue<StrongBox<T>>.的用法或示例我从谷歌找到的只有this code.

1 个答案:

答案 0 :(得分:7)

提醒过早优化的危险在评论中,所以我将解决这里发生的事情的语义。

就像文章所指出的那样,ConcurrentQueue可以继续引用已经经历过的一些事情。我把它学到了“几打”,文章说它不超过31,这看起来很漂亮。如果队列正在跟踪大对象,例如2000x2000位图,理论上这可能会成为一个问题。当然,这取决于你的程序的其余部分。

将其包含在StrongBox<T>中会有所帮助,因为StrongBox唯一能做的就是保留对其他内容的引用。因此,StrongBox具有非常小的占用空间,无论它持有什么都将超出范围并且(理论上)更快地获得GC。

由于StrongBox含有减肥苏打水的所有内容,所以你有点过分思考它的用法。您实际上只是使用Value加载T字段,然后再引用它。它看起来有点像这样:

var boxedBitmap = new StrongBox<Bitmap>(new Bitmap(1,1));
var bitmap = boxedBitmap.Value;

或者:

var boxedBitmap = new StrongBox<Bitmap>();
boxedBitmap.Value = new Bitmap(1,1);
var bitmap = boxedBitmap.Value;

说真的,如果你在Reflector中打开它,这个类的实现就像是5行。

在这种情况下,ConcurrentQueue<T>的使用与ConcurrentQueue<StrongBox<T>>的使用没有任何不同。在将资源发送到目标线程之前,您只需要在.Value上进行操作。这确实帮助了我工作的公司通过简单地传递对确定性工具的引用而不是通过整个工具来减少大规模多线程分析服务的内存印记,但是你的里程可能会有所不同 - 我不清楚如果你传递的东西要被改变然后被其他东西使用,它将会产生什么影响。