我有WCF网络服务,用于将图像从我的Windows Mobile客户端应用程序发送到我的服务器。
当我尝试发送图像时,我无法同时从我的数据库中加载所有图像,否则我将获得内存不足异常。所以我想我将以10个左右的批次调用我的Web服务。
我想知道的是,如果我一次设置IEnumerable
和yield
来自数据库1的图像,是否会在发送每个批次后释放内存?
我知道依靠垃圾收集器进行快速清理通常是个坏主意。所以我犹豫不决(因此我要问的原因)。
我能看到的唯一另一个选择是调用数据库来获取10组数据(看起来不太优雅,但我可能不得不这样做。)
让我用一个例子来总结一下。说我有以下代码。 yield(MyYieldingEnumerable)返回的项目何时可以释放内存(或至少可用于垃圾回收)?
public void SendImages()
{
List<ImageItem> itemsToSend = new List<ImageItem>();
int count = 0;
foreach (ImageItem curImageItem in MyYieldingEnumerable())
{
itemsToSend.Add(curImageItem);
count++;
if (count >= 10)
{
myService.SendItems(itemsToSend);
// #1 When the last reference to it is removed
// |
// v
itemsToSend = new List<ImageItem>();
count = 0;
}
}
// <----- #2 After the loop ends
}
// <------- #3 After the method exits
他们是否会在10个项目的内存中存在,或者它们是否会同时存在于内存中?
答案 0 :(得分:4)
这取决于您的代码在MyYieldingEnumerable
中执行的操作以及boxes
列表的创建方式。 itemsToSend
列表除非被myService.SendItems
调用保持活动,否则将被取消引用,因此GC可以回收它。但是,有太多的代码缺少判决。
但真正的问题不是这个代码,而是处理文件传输的整体方法。将整个文件加载到内存中并将它们传递给WCF代理只是在现实生活中无法运行。单独一个文件可能足以破坏您的应用程序,因此批处理10不会保存任何内容。您需要实现端到端的清晰流式语义:从客户端以块的形式读取文件,以块的形式发送它,以及以块的形式将其写入目标。如果这些文件传输操作是应用程序的面包和黄油然后恢复(能够从某个偏移恢复文件传输)并且可能公平性(一个大文件不会中断每个其他文件)也可能是要求。
我建议您在MSDN中查看此主题:WCF How to: Enable Streaming。