gpt4 book ai didi

c# - 与 ManualResetEvent 同步时出现问题

转载 作者:行者123 更新时间:2023-11-30 15:10:32 25 4
gpt4 key购买 nike

我写了一个下载一些文件的方法,现在我试图让它并行下载最多 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();
}
}
}

我做错了什么吗?

它是用适用于 Windows Phone 7 的 Silverlight 4 编写的。

编辑:Silverlight 4 中没有 Semaphore 或 SemaphoreSlim。

最佳答案

我在评论中的意思是当您可以使用 Interlocked 时使用慢速 lock。这种方式也会提高性能。

最多同时进行 5 个下载:

public class Downloader
{
private int fileCount = 0;
private AutoResetEvent sync = new AutoResetEvent(false);

private void StartNewDownload(object o)
{
if (Interlocked.Increment(ref this.fileCount) > 5) this.sync.WaitOne();

WebClient downloadClient = new WebClient();
downloadClient.OpenReadCompleted += downloadClient_OpenReadCompleted;
downloadClient.OpenReadAsync(new Uri(o.ToString(), UriKind.Absolute));
}

private void downloadClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
// Download logic goes here.
}
catch {}
finally
{
this.sync.Set();
Interlocked.Decrement(ref this.fileCount);
}
}

public void Run()
{
string o = "url1";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);
Thread.Sleep(100);

o = "url2";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);

o = "url3";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);
Thread.Sleep(200);

o = "url4";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);

o = "url5";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);

o = "url6";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);

o = "url7";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);
Thread.Sleep(200);

o = "url8";
System.Threading.ThreadPool.QueueUserWorkItem(this.StartNewDownload, o);
Thread.Sleep(400);
}
}

关于c# - 与 ManualResetEvent 同步时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3288307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com