2013-12-07 94 views
4

我在我的應用程序中使用TaskTaskCompletionSource代碼在經常調用的場景中,例如從「滾動表視圖」異步下載圖像。這使我可以編寫異步/等待代碼,而無需觸摸UI線程進行下載/緩存操作。MonoTouch應用程序中的線程數

例如爲:

public override Task<object> GetCachedImage (string key) 
    { 
     UIImage inMemoryImage = sdImageCache.ImageFromMemoryCache (key); 

     // 
     // Return synchronously since the image was found in the memory cache. 
     if (inMemoryImage != null) { 
      return Task.FromResult ((object)inMemoryImage); 
     } 

     TaskCompletionSource<object> tsc = new TaskCompletionSource<object>(); 

     // 
     // Query the disk cache asynchronously, invoking the result asynchronously. 
     sdImageCache.QueryDiskCache (key, (image, cacheType) => { 
      tsc.TrySetResult (image); 
     }); 

     return tsc.Task; 
    } 

GetCachedImage被調用多次,因爲表格視圖可以具有大量的圖像的要被下載,並且用戶可以滾動表格視圖中。 任務本身執行時間不會太長(在某些情況下,結果會同步返回),所以我期望系統創建大量線程,但也會重用它們。但是我看到控制檯輸出如下:

Thread finished: <Thread Pool> #149

線程的數量總是變得越來越大,我擔心我的應用程序創建過多的線程,經過長期可能會因爲這個卡住使用期限。 Thread finished: <Thread Pool> #149是什麼意思?線程是否正在創建和銷燬?線程是否被重用?我的應用程序是否有#149活動線程?我可以(應該)限制最大線程數量嗎?


編輯

至於建議由@usr我又跑我的應用程序,並停止調試器,看看多少線程在那裏,看截圖: Debugger threads Debugger console

看起來像創建了38個線程,但其中一些被破壞了,我是對的? 這是否意味着只要應用程序正在運行,Thread finished: <Thread Pool> #...消息總是會以更大的數字出現?爲什麼不重新使用線程?

+1

爲什麼系統甚至會創建任何線程?我沒有看到任何會在您的代碼中創建線程的東西。 – svick

+0

我不是'ThreadPool'專家,但我可以在文檔中看到'Task'使用'ThreadPool'線程在後臺執行工作。問題是'爲什麼太多線程正在創建'? –

+0

如果你使用'Task.Run()'或類似的東西,當然。但是如果你使用'Task.FromResult()'或'TaskCompletionSource',則不行,因爲那樣就沒有工作要做。 – svick

回答

2

「應用程序輸出」中顯示的線程號是創建的第n個線程,而不是第n個正在運行的線程。

例如:

Thread started: <Thread Pool> #123 

意味着在整個應用程序的生命週期123個線程已經開始。它沒有提到有多少線程正在運行。

相反消息:

Thread finished: <Thread Pool> #123 

意味着該線程已退出。

,如果您現在創建一個新的線程,你會看到這一點:

Thread started: <Thread Pool> #124 

這意味着,要知道很多線程的方式正在運行,你可以指望的「主題開始」線的數量和減去「線程完成」行的數量。

另一種解決方案是隻看線程面板(比如你的屏幕截圖),然後統計那裏的線程數。