【发布时间】:2010-07-20 08:45:11
【问题描述】:
我已经编写了一个下载一些文件的方法,现在我正试图让它并行下载多达 5 个文件,其余的等待前面的文件完成。 我为此使用了 ManualResetEvent,但是当我包含同步部分时,它不再下载任何东西(没有它就可以工作)。
这里是方法的代码:
static readonly int maxFiles = 5;
static int files = 0;
static object filesLocker = new object();
static System.Threading.ManualResetEvent sync = new System.Threading.ManualResetEvent(true);
/// <summary>
/// Download a file from wikipedia asynchronously
/// </summary>
/// <param name="filename"></param>
public void DoanloadFileAsync(string filename)
{
...
System.Threading.ThreadPool.QueueUserWorkItem(
(o) =>
{
bool loop = true;
while (loop)
if (sync.WaitOne())
lock (filesLocker)
{
if (files < maxFiles)
{
++files;
if (files == maxFiles)
sync.Reset();
loop = false;
}
}
try
{
WebClient downloadClient = new WebClient();
downloadClient.OpenReadCompleted += new OpenReadCompletedEventHandler(downloadClient_OpenReadCompleted);
downloadClient.OpenReadAsync(new Uri(url, UriKind.Absolute));
//5 of them do get here
}
catch
{
lock (filesLocker)
{
--files;
sync.Set();
}
throw;
}
});
}
void downloadClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
//but none of the 5 get here
...Download logic... //works without the ManualResetEvent
}
finally
{
lock (filesLocker)
{
--files;
sync.Set();
}
}
}
我是不是做错了什么?
它是用 Silverlight 4 for Windows Phone 7 编写的。
编辑:Silverlight 4 中没有 Semaphore 或 SemaphoreSlim。
【问题讨论】:
-
可以使用
System.Threading.Interlocked.Decrement()等方法时为什么要锁定? -
因为我也想调用sync.Set(),而且我认为有人从另一个线程冷调用sync.Set(),然后我递减,一些线程递增并调用sync.Reset(),然后我调用 sync.Set() 并获得更多的 maxFiles 线程下载。
-
检查我的答案,这就是你要找的。此外,使用重置事件是可以的,我只是不认为需要锁。哦,我使用 AutoResetEvent,因为它正是您需要的。
标签: c# synchronization silverlight-4.0 windows-phone-7