mpe*_*pen 3 c# queue thread-safety
我正在尝试使用WebClient异步下载一堆文件.根据我的理解,这是可能的,但WebClient每次下载需要有一个对象.所以我想我只是在我的程序开始时把一堆它们放在一个队列中,然后一次一个地弹出它们并告诉它们下载一个文件.文件下载完成后,可以将它们推回队列.
把东西推到队列上应该不会太糟糕,我只需要做一些事情:
lock(queue) {
queue.Enqueue(webClient);
}
Run Code Online (Sandbox Code Playgroud)
对?但是把它们弹出来呢?我希望我的主线程在队列为空时休眠(等到另一个Web客户端准备就绪,以便它可以开始下一次下载).我想我可以使用Semaphore队列旁边的队列来跟踪队列中有多少元素,这会让我的线程在必要时进入休眠状态,但这似乎不是一个很好的解决方案.如果每次推送/弹出我的队列中的某些内容并且它们不同步时我忘记减少/增加我的信号量会发生什么?那会很糟糕.是不是有一些很好的方式queue.Dequeue()自动睡觉,直到有一个项目出队然后继续?
我也欢迎不涉及队列的解决方案.我只是想出一个队列将是跟踪哪些WebClient可以使用的最简单方法.
这是使用信号量的示例.IMO比使用Monitor更清洁:
public class BlockingQueue<T>
{
Queue<T> _queue = new Queue<T>();
Semaphore _sem = new Semaphore(0, Int32.MaxValue);
public void Enqueue(T item)
{
lock (_queue)
{
_queue.Enqueue(item);
}
_sem.Release();
}
public T Dequeue()
{
_sem.WaitOne();
lock (_queue)
{
return _queue.Dequeue();
}
}
}
Run Code Online (Sandbox Code Playgroud)