11

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

如果元素很小,您可能永远不会注意到这一点。但是,如果元素占用大量资源(例如,每个元素都是一个巨大的图像位图),您可能会看到这种影响(一种解决方法是将包装器对象排队,例如使用 a ConcurrentQueue<StrongBox<T>>而不是 aConcurrentQueue<T>和 null在包装器出队后,包装器对 T 值的引用)。

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

所以我正在寻找ConcurrentQueue<StrongBox<T>>.我从谷歌找到的唯一的东西就是这个代码的用法或例子。

4

1 回答 1

8

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

就像文章指出的那样,ConcurrentQueue可以保留一些已经经历过的事情的参考。我知道它是“几十个”,文章说它不超过 31 个,这似乎很好地凝结。如果队列正在跟踪大对象,例如 2000x2000 位图,理论上这可能会成为问题。当然,这取决于程序的其余部分在做什么。

将其包装在StrongBox<T>帮助中,因为唯一要做的StrongBox就是保持对其他事物的引用。因此,aStrongBox的占用空间非常小,它所拥有的任何东西都将超出范围并且(理论上)更快地获得 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在将资源发送到其目标线程之前,您只需执行此操作。这确实帮助我工作的一家公司通过简单地传递对确定性工具的引用而不是传递整个工具来减少大量多线程分析服务的内存印记,但你的里程可能会有所不同 - 我不清楚如果您传递要突变的东西然后被其他东西使用,将会产生什么后果。

于 2012-11-28T21:58:03.217 回答