我想我可能需要重新考慮我的設計。我很難縮小一個導致我的電腦完全掛起的錯誤,有時會拋出VS 2010的HRESULT 0x8007000E。線程池/ WaitHandle資源泄漏/崩潰
我有一個控制檯應用程序(我將稍後轉換爲服務)基於數據庫隊列傳輸文件。
我限制了允許傳輸的線程。這是因爲我們連接的某些系統只能包含來自特定帳戶的一定數量的連接。
例如,系統A只能接受3個同時連接(這意味着3個獨立的線程)。這些線程中的每一個都有自己獨特的連接對象,所以我們不應該遇到任何同步問題,因爲它們沒有共享連接。
我們想循環處理來自這些系統的文件。因此,例如,我們將允許3個連接,每個連接最多可傳輸100個文件。這意味着,要從系統A移動1000個文件,我們每個週期只能處理300個文件,因爲每個文件允許3個線程,每個文件有100個文件。因此,在這個轉移的整個生命週期中,我們將有10個線程。我們一次只能運行3個。所以,會有3個週期,最後一個週期只會使用1個線程來傳輸最後的100個文件。 (3個線程×100個=文件每循環300名的文件)
現行的結構通過例子是:
- 甲System.Threading.Timer檢查每5秒的東西通過調用GetScheduledTask做隊列()
- 如果沒有什麼,GetScheduledTask()簡單地什麼也不做
- 如果有工作,創建一個線程池線程來處理工作[工作線程A]
- 工作線程A看到,有1000個文件傳輸
- 工作線程A看到,它只能有3個線程中運行的系統中,它從
- 工作線程A獲取文件啓動三個新的工作線程[B,C,d]和轉讓
- 工作線程用於等待B,C,d
[WaitHandle.WaitAll(transfersArray)]
- 工作線程A看到有隊列更文件(應該是700現在)
- 工作線程A創建一個新的陣列上等待
[transfersArray = new TransferArray[3]
這是最大的系統A,但可能會在系統上有所不同 - 工作線程A啓動三個新工作線程[B,C,D]並等待它們
[WaitHandle.WaitAll(transfersArray)]
- 該過程重複,直到沒有更多的文件要移動。
- ,它是做
工作線程A信號,我使用的ManualResetEvent來處理信號。
我的問題是:
- 是否有任何明顯的情況下,這將導致該我遇到資源泄漏或問題?
- 我應該循環數組通每一個
WaitHandle.WaitAll(array)
後,並呼籲array[index].Dispose()?
- 任務管理器下句柄計數此過程中慢慢爬行
- 我打電話工作者線程A的從的System.Threading初始創建。計時器。這會有什麼問題嗎?該定時器的代碼是:
(用於調度一些類代碼)
private ManualResetEvent _ResetEvent;
private void Start()
{
_IsAlive = true;
ManualResetEvent transferResetEvent = new ManualResetEvent(false);
//Set the scheduler timer to 5 second intervals
_ScheduledTasks = new Timer(new TimerCallback(ScheduledTasks_Tick), transferResetEvent, 200, 5000);
}
private void ScheduledTasks_Tick(object state)
{
ManualResetEvent resetEvent = null;
try
{
resetEvent = (ManualResetEvent)state;
//Block timer until GetScheduledTasks() finishes
_ScheduledTasks.Change(Timeout.Infinite, Timeout.Infinite);
GetScheduledTasks();
}
finally
{
_ScheduledTasks.Change(5000, 5000);
Console.WriteLine("{0} [Main] GetScheduledTasks() finished", DateTime.Now.ToString("MMddyy HH:mm:ss:fff"));
resetEvent.Set();
}
}
private void GetScheduledTask()
{
try
{
//Check to see if the database connection is still up
if (!_IsAlive)
{
//Handle
_ConnectionLostNotification = true;
return;
}
//Get scheduled records from the database
ISchedulerTask task = null;
using (DataTable dt = FastSql.ExecuteDataTable(
_ConnectionString, "hidden for security", System.Data.CommandType.StoredProcedure,
new List<FastSqlParam>() { new FastSqlParam(ParameterDirection.Input, SqlDbType.VarChar, "@ProcessMachineName", Environment.MachineName) })) //call to static class
{
if (dt != null)
{
if (dt.Rows.Count == 1)
{ //Only 1 row is allowed
DataRow dr = dt.Rows[0];
//Get task information
TransferParam.TaskType taskType = (TransferParam.TaskType)Enum.Parse(typeof(TransferParam.TaskType), dr["TaskTypeId"].ToString());
task = ScheduledTaskFactory.CreateScheduledTask(taskType);
task.Description = dr["Description"].ToString();
task.IsEnabled = (bool)dr["IsEnabled"];
task.IsProcessing = (bool)dr["IsProcessing"];
task.IsManualLaunch = (bool)dr["IsManualLaunch"];
task.ProcessMachineName = dr["ProcessMachineName"].ToString();
task.NextRun = (DateTime)dr["NextRun"];
task.PostProcessNotification = (bool)dr["NotifyPostProcess"];
task.PreProcessNotification = (bool)dr["NotifyPreProcess"];
task.Priority = (TransferParam.Priority)Enum.Parse(typeof(TransferParam.SystemType), dr["PriorityId"].ToString());
task.SleepMinutes = (int)dr["SleepMinutes"];
task.ScheduleId = (int)dr["ScheduleId"];
task.CurrentRuns = (int)dr["CurrentRuns"];
task.TotalRuns = (int)dr["TotalRuns"];
SchedulerTask scheduledTask = new SchedulerTask(new ManualResetEvent(false), task);
//Queue up task to worker thread and start
ThreadPool.QueueUserWorkItem(new WaitCallback(this.ThreadProc), scheduledTask);
}
}
}
}
catch (Exception ex)
{
//Handle
}
}
private void ThreadProc(object taskObject)
{
SchedulerTask task = (SchedulerTask)taskObject;
ScheduledTaskEngine engine = null;
try
{
engine = SchedulerTaskEngineFactory.CreateTaskEngine(task.Task, _ConnectionString);
engine.StartTask(task.Task);
}
catch (Exception ex)
{
//Handle
}
finally
{
task.TaskResetEvent.Set();
task.TaskResetEvent.Dispose();
}
}
好像這是一個編碼錯誤,與聲明重置事件數組有關。我是做 'ManualResetEvent的[]事件=新ManualResetEvents [統計]' 而不是 '的WaitHandle [] =事件的WaitHandle新[計]' – 2010-07-19 18:16:01