2016-02-29 218 views
0

當我運行下面的代碼,拋出一個OutOfMemoryException異常:爲什麼異常不會被拋出?

static void Main(string[] args) 
{ 
    for (int i = 0; i < 200; i++) 
    { 
     Stream filestream = new MemoryStream(Resources.File); // Resources.File is typeof byte[] 
     ThreadPool.QueueUserWorkItem(ThreadProc, filestream); 
    } 
    Thread.Sleep(999999999); 
} 

private static void ThreadProc(object stream) 
{ 
    // Document is 3rd party's class 
    Document doc = new Document((Stream)stream); // OutOfMemoryException is thrown after 160 iterations 
} 

但是,如果我裏面創建「ThreadProc的」方法的流 - 沒有例外:

static void Main(string[] args) 
{ 
    for (int i = 0; i < 200; i++) 
    { 
     ThreadPool.QueueUserWorkItem(ThreadProc, null); 
    } 
    Thread.Sleep(999999999); 
} 

private static void ThreadProc(object stream) 
{ 
    Stream filestream = new MemoryStream(Resources.File); 
    Document doc = new Document(filestream); // Exception is NOT thrown 
} 

爲什麼會出現區別?

+0

'ThreadProc'只在線程可用時執行,因此只會創建內存流的頻率較低,從而允許垃圾回收器釋放更多連續內存。 – user1666620

+0

對於其中一種情況,在第二種情況下,您創建這些內存流的速率受限於您正在運行的工作線程數量,並且一旦處理完流,它就有資格進行垃圾收集。在第一種情況下,您首先創建所有流,然後隨時間處理*,這意味着您同時打開了大約200個流,無法進行垃圾回收。也就是說,MemoryStream應該不是什麼昂貴的東西,Resources.File可能是罪魁禍首,隱藏在MemoryStream中。 – Luaan

+0

當您運行調試版本或附加調試器時,此代碼的行爲不一樣。與線程無關,將代碼移動到另一個方法就足夠了。 Backgrounder [在這裏](http://stackoverflow.com/a/17131389/17034)。 –

回答

6

因爲第一個總是分配循環中的所有內存流。

seond one只在線程運行時分配它們。由於您在線程池中運行,因此它們不會一次全部運行

相關問題