我正在做一个小小的下载管理器与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