我使用ConcurrentQueue(C#,ASP.NET核心),用于保持任务的大文件的上传。我有一个项目从并发队列离队后也有非常大的内存消耗。项目不从内存中清除。
我明白在ASP.NET核心的ConcurrentQueue这是在短的行为:每个组中的并发队列32项被保存在单独的段。引用发布取出的物品后,才从特定段的所有项目都出队,而不是后TryDequeue()方法被调用单个项目。这是在我的情况的问题,因为我可以在存储量非常大,如果在最坏的情况下,32个项目未清理,这是潜在的非常大的zip文件。我甚至不希望在同一时间在队列中超过32项。
即使我提取文件,并分别给他们,每一个文件/图片里面也可以通过自身大。这是个好足以让我的唯一的事情是释放每一个取出的物品的参考,而不作进一步推迟。是否可能,如何?
我试图用StrongBox的,在一些文章建议:
ConcurrentQueue<StrongBox<Func<CancellationToken, Task>>>
workItems = new ConcurrentQueue<StrongBox<Func<CancellationToken, Task>>>();
// Enqueuing:
this.workItems.Enqueue(new StrongBox<Func<CancellationToken, Task>>(workItem));
// Dequeuing:
workItems.TryDequeue(out var workItem);
return workItem.Value;
这不是在我的情况非常有用。内存是不会释放。我不知道我的问题是有关,我送参考功能,队列中的事实,它是在一个内存莫名其妙举行。一个这个函数的参数是要上传的文件的混凝土。其他人则只是字符串。
最后,我想照顾内存释放的该项目,之后或期间TryDequeue()方法被调用。是否可能,如何?
看到这里接受答案的评论:Usage of ConcurrentQueue<StrongBox<T>>。
这个想法是,你可以空Value
的StrongBox
财产。所以,你的代码就变成了:
// Dequeuing:
workItems.TryDequeue(out var workItem);
var returnValue = workItem.Value;
workItem.Value = null; // see below
return returnValue;
通过设置workItem.Value = null
,你删除了StrongBox
持有该项目的参考。所以,一旦你的代码是用它做有该项目的更多引用,它可以收集。当然,队列继续保持到StrongBox
一个参考,但是那个东西是微小的。