我知道WaitAll ManualResetEvents的限制,即64.(因爲64的任何原因) 由於這個限制,當我使用SourceFolders.Count> 64.線程池等待所有64 [Leadtools]
if (Source.SubFolders.Count > 0)
{
var threadPoolDoneEvents = new ManualResetEvent[Source.SubFolders.Count];
for (int i = 0; i < Source.SubFolders.Count; i++)
{
try
{
if (m_bRegisterCancelled == false)
{
threadPoolDoneEvents[i] = new ManualResetEvent(false);
AddSourceAgs variables = new AddSourceAgs();
variables.Source = Source;
variables.SubFolder = Source.SubFolders[i];
variables.DoneEvents = threadPoolDoneEvents[i];
ThreadPool.QueueUserWorkItem(AddSourceProcess, variables);
}
else
{
break;
}
}
catch (System.Exception Ex)
{
FireError(this, "AddSource", this.ExBuilder.Message(ERROR_CASE_DATABASE_ADD_SOURCE_EX), Ex);
}
}
WaitHandle.WaitAll(threadPoolDoneEvents);
}
我試圖替換下面的行:
WaitHandle.WaitAll(threadPoolDoneEvents);
通過該:
foreach (var waitHandle in threadPoolDoneEvents)
waitHandle.WaitOne();
由此導致意想不到的事情發生 - 在我的情況下,100個文件中,隨機20 - 30個文件完全處理,然後休息停在兩者之間。 任何想法,我的概念落後?任何解決這個問題的方法?我嘗試過this,但這也會導致一些隨機錯誤,例如處理每個任務兩次或類似的事情。
UPDATE 調試後,我發現任務失敗,因爲扔在這行代碼的異常:
try
{
RasterImage image = m_codecs.Load(m_documentNameWithPath, pageNum);
m_codecs.Save(image, m_outputPath+ "\\\\" + pageNum.ToString("D4") + ".png", RasterImageFormat.Png, 0);
return true;
}
catch (Exception Ex)
{
m_conversionErrors.Add(Ex);
return false;
}
以下是拋出異常:
Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation.
任何解決方案是否做到甚至解釋這是什麼?
這是底層winapi函數WaitForMultipleObjects()中的一個硬性限制。從技術上講,限制可能會增加到128,但微軟拒絕修復它。當然是因爲他們認爲程序員不應該編寫使用多於64個線程的程序。這對你的代碼來說是準確的,它只會在* one *線程中表現良好。你只有一個磁盤,它不喜歡被多個線程指定。磁盤尋求可以完全殺死你的應用程序的性能。在調試時,文件系統緩存將隱藏此問題,這在生產中不會發生。 – 2014-10-16 12:55:14