我正在做一個小小的下載管理器與C#和WPF。在C中使用多線程的正確方法
在我的邏輯中有一個主線程(用於UI),用於管理連接的線程和每個下載的線程,直到我用信號量定義的最大下載數量。
每當用戶想要下載某個東西時,它會在共享隊列中添加一個自定義對象DownloadDetails
,連接線程會將其解除鎖定並使另一個線程執行實際下載。
對於單個文件,它工作正常,但對於多個文件看起來像更多的線程嘗試下載相同的文件,試圖寫入本地驅動器上的相同文件,並在寫入流時崩潰。
這裏我實現的一些片段
在主要形式:
private Thread connectionManager;
時clickin下載我添加新的下載(他們是正確的,我檢查),並啓動連接線只有當它尚未啓動:
downloadList.Enqueue(newDownload);
if (connectionManager == null || !connectionManager.IsAlive)
{
connectionManager = new Thread((ThreadStart)delegate
{
ManageDownload();
});
connectionManager.SetApartmentState(ApartmentState.STA);
connectionManager.IsBackground = true;
connectionManager.Start();
}
的下載管理器線程做到這一點:
private void ThreadStartingPoint()
{
downloadDetails singleDownload = new downloadDetails();
while (downloadList.TryDequeue(out singleDownload))
{
downloadSemaphore.WaitOne();
Thread singleDownloadThread = new Thread((ThreadStart)delegate
{
myDownloadClass.Download(singleDownload);
});
singleDownloadThread.SetApartmentState(ApartmentState.STA);
singleDownloadThread.IsBackground = false;
singleDownloadThread.Start();
}
}
完成下載(或取消,或者得到一個錯誤),單線程後做downloadSemaphore.Release();
的問題是,myDownloadClass.Download看起來得到多個開始2個或更多下載時迅速
時間相同的參數,我有,因爲單一的下載線程需要在主線程
更新UI使用委託0我該如何解決這個問題?謝謝:)
你確定嗎?調試它我總是有一個不同的值,因爲「TryDequeue」實際上是從隊列中刪除值...並且此循環由單個線程完成,因此無法在同一時刻多次完成 – HypeZ
嘗試使用localCopy固定。它適合_looks像更多的線程嘗試下載相同的file_症狀。 –
嘗試..和..工作!謝謝:)但我仍然不明白它爲什麼會起作用,這怎麼會發生呢? – HypeZ