2011-11-02 65 views
1

我有一個要加密的文件列表。
加密是由外部控制檯應用程序進程報告必須進行分析的進度。 此進度必須啓動異步(處理OutputDataReceived事件的Process.BeginOutputReadLine是我可以從此進程獲得實時進度的唯一方法)。運行一批進程並報告每個進程的進度

場景:
對於用戶選擇來加密每個文件,含有這個文件信息一個ViewModel實例被添加到一個ListBox。用戶添加了100個文件進行加密。每個ViewModel s都有一個Encrypt命令(我使用Prism DelegateCommand),當用戶單擊列表項上的加密按鈕時應該觸發該命令。

除此之外,用戶可以選擇單擊「加密全部」,這是對每個單獨項目調用加密命令的父容器中的CompositeCommand
列表中的每個項目都有一個進度條,指示該單個文件的加密過程,並且父容器中還有一個應顯示整體進度的進度條。

我做了一個包裝程序,它異步調用該進程並在每次進程更改時觸發一個.NET事件,VM處理該事件並更新其進度欄綁定到的進度屬性,並且該事件也由父級每個進度變更重置總結進度欄的容器。
這個包裝器公開了一個啓動底層進程的「EncryptAsync」函數。
每個項目(VMs)都有一個包裝器,當調用Encrypt命令時,它會在包裝器上調用這個方法,然後創建一個進程等。
所以基本上當用戶單擊Encrypt All時,100個進程將開始。

只是爲了確保每個文件的加密可能需要10分鐘甚至更多時間。平均是一分鐘或更少。

現在我的問題是

  1. 如何限制併發進程的數量(我不得不或許我應該通過加密1其中1個?)?
  2. 這是做到這一點的有效方法嗎?也許有一個完全不同的,更好的方法?
  3. 當ViewModel關閉時,我如何確保所有這些進程(位於駐留在VM中的包裝中的這些進程)公開(盡我所能在加密之後在內部部署資源(即加密進程本身)但我做了包皮實施IDisposable,我不知道在虛擬機上執行IDisposable將是正確的方式,我錯了。

任何設計或實際指導/關於這個故事的樣本引用將不勝感激!

* Dispose

回答

1

1和2
我會強烈建議你看看How to: Use a Thread Pool (C# and Visual Basic) MSDN上。
尤其是ThreadPoolExample級 - 它爲你的問題的解決方案


如果你的意思是「繼續加密後查看/ VM關閉」:創建一個靜態類的TreadPool處理。

+0

響應3 - 否 - 虛擬機關閉後永遠不會轉換。 我只是想確保當虛擬機停機時(或者甚至更多 - 該項目從列表中刪除),它應該處理底層包裝 - >過程),基本上我需要知道對虛擬機有更多的控制權,我認爲這是一個單獨的問題,即「如何使用棱鏡來部署虛擬機」,我相信我會在Google上找到一些信息。謝謝。 – Shimmy

+0

請看看[this](http://stackoverflow.com/questions/2043909/threadpool-setmaxthreads-and-setminthreads-magic-number/2044198#2044198)文章。你確定我應該使用'ThreadPool'嗎?我真的很喜歡,問題是如果這是一個好主意。 – Shimmy

1

我們在一個服務中生成報告時可能會同時請求幾十個長時間運行的報告,這與此類似。我們處理資源消耗的方式是將每個報告關閉到其自己的線程中,但將執行線程的最大數量限制爲設定的數量。

生成的每個線程都會記錄在字典變量中,該字典變量使用在生成線程時分配給該線程的鍵。主控制進程執行連續循環(每循環大概100ms休眠),並檢查每個正在運行的線程以完成每個循環。

一旦一個線程被識別爲已經完成,它就會從字典中移除,並且隊列中的下一個被產生爲一個新的線程。

由於執行線程的列表始終可用,因此我們可以優雅地處理提前終止請求和其他異常活動。如果我們需要爲用戶提供流程,那麼嵌入活動流程將非常簡單。

作爲一個參考點,生成的報告線程實際上是包含它們正在執行的線程對象的類。這使我們可以控制線程或向父進程提供反饋,而無需跳過很多環節(只需確保您對從線程外部和內部訪問的任何資源進行了synclock)。

+0

我決定使用'ThreadPool'。它從字面上爲我做了這份工作。查看邁克爾的答案。 – Shimmy