2010-10-22 102 views
2

我有WCF Web服務,用於將圖像從Windows Mobile客戶端應用程序發送到我的服務器。產量和釋放內存

當我嘗試發送圖像時,我無法同時從我的數據庫中加載所有圖像,否則我會得到內存不足異常。所以我想我會撥打我的網絡服務批量10左右。

我想知道的是,如果我一次設置IEnumerableyield來自數據庫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個批次的內存中存儲,還是都會在同一時間內存到內存中?

回答

4

這取決於您的代碼在MyYieldingEnumerable中的作用,以及如何創建boxes列表。除非myService.SendItems調用保持活動狀態,否則itemsToSend列表將不被引用,因此GC可以回收它。但是缺少太多的代碼來判定結果。

但真正的問題不在於此代碼,而在於您處理文件傳輸的整體方法。將整個文件加載到內存中並將它們傳遞給WCF代理只是在現實生活中不起作用。單獨一個文件可能足以毀壞您的應用程序,因此批處理10不會保存任何內容。您需要實現清晰的流式語義,端到端:以塊讀取客戶端上的文件,以塊爲單位發送,並以塊爲單位將其寫入目標。如果這些文件傳輸操作是應用程序的麪包和黃油,然後恢復(能夠從某個偏移量恢復文件傳輸),也許公平性(一個大文件不會中斷每個其他文件)也可能是需求。

我建議你在MSDN:WCF How to: Enable Streaming這個主題。

+0

謝謝你的回覆。我看着流媒體。我問是否會幫助我的情況在這裏:http://stackoverflow.com/questions/3999842/does-streaming-a-wcf-soap-help-the-client-send-using-less-memory我得到的答案表明流媒體不會幫助我。至於缺少的代碼,大部分都沒有寫入。然而,我可以做到最好。我發送的文件是已知的大小(它們是我的應用程序創建的截圖)。注意:'Boxes'是我用來製作這個例子的代碼中的一個剩餘部分。正如我所看到的,這個示例方法應該沒有參數。 – Vaccano 2010-10-23 02:19:17

+0

我會仔細檢查,但我很確定你在流式問題上的答案顯然是錯誤的。 – 2010-10-23 03:40:11