webrequests c多线程程序#
我想制作多线程异步下载管理器。但是我有多线程问题。 一个线程正常工作,但是当我创建第二个线程时 - 什么都不工作。 我认为webrequest的同步问题。我读了这个回答Multithreading a large number of web requests in c#,但我完全不明白。现在问题:我如何修改代码以使用多线程(线程,线程池)。webrequests c多线程程序#
类DownloadableContent
:
{
private string url { get; set; }
private string path { get; set; }
private Stream streamResponse { get; set; }
private Stream streamLocal { get; set; }
private HttpWebRequest webRequest { get; set; }
private HttpWebResponse webResponse { get; set; }
public DownloadableContent(string url, string path)
{
this.url = url;
this.path = path;
}
public void Download()
{
using (WebClient wcDownload = new WebClient())
{
try
{
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webResponse = (HttpWebResponse)webRequest.GetResponse();
Int64 fileSize = webResponse.ContentLength;
streamResponse = wcDownload.OpenRead(url);
streamLocal = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
byte[] downBuffer = new byte[2048];
int bytesSize = 0;
while ((bytesSize = streamResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
streamLocal.Write(downBuffer, 0, bytesSize);
}
}
finally
{
streamResponse.Close();
streamLocal.Close();
}
}
}
}
而且main
类:
DownloadableContent file = new DownloadableContent("url", @"path");
Thread thread = new Thread(file.Download);
thread.Start();
这是值得您阅读异步编程 然后看看这个 http://msdn.microsoft.com/en-us/library/System.Net.WebClient_methods(v=vs.110).aspx 你有没有办法下载的东西异步。 也看看TPL,并避免线程 http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
大概多读一点会帮助你避免很多头痛。
这是一个简单的例子
private static void Main(string[] args)
{
var urlsAndPaths = new Dictionary<string, string>();
urlsAndPaths.Add("http://i.forbesimg.com/media/lists/people/lionel-messi_416x416.jpg","messi.jpg");
urlsAndPaths.Add("http://sizzlingsuperstars.com/wp-content/uploads/2014/07/Cristiano-Ronaldo-2-480x309.jpg", "cristiano.jpg");
foreach (var kvp in urlsAndPaths)
{
var wc = new WebClient();
wc.DownloadFileAsync(new Uri(kvp.Key),kvp.Value);
}
Console.ReadKey();
}
感谢您的回答,看起来不错,但是程序条件是“New Thread in New Thread”(训练任务)使用Thread和Threadpool。 (两个不同的实现) – 2014-09-26 13:24:49
我认为有人需要更新他们的培训材料:) – 2014-09-26 14:22:19
这是新手的任务。NET :) – 2014-09-27 15:35:07
根据您所使用的.NET framework版本,你可以利用任务类的。你可以这样做
foreach (var uri in myCollection)
{
Task.Factory.StartNew(() =>
{
try
{
using (System.Net.WebClient client = new System.Net.WebClient())
{
client.DownloadFileCompleted += (o, args) =>
{
//Do something with the download
};
client.DownloadFileAsync(uri);
}
}
catch (Exception ex)
{
//Do something
}
});
}
我可以给你的最好的建议是使用TPL。这是一个从微软到管理线程的好库。在我的代码中,我曾使用过这个类似的问题,基本上我必须下载8000个URL,开始时正常过程需要30分钟。使用这个库后,同样的过程在30秒内完成。
TPL LINK
请,拿在例子看看:
你在.NET 4.5?这样做的“新方法”是Task.WhenAll
,它可以使异步下载异步并行,但允许框架决定是否/何时将工作安排到线程池。
var client = new System.Net.WebClient();
await Task.WhenAll(urls.Select(url => {
var path = ?? // build local path based on url?
return client.DownloadFileAsync(url, path);
});
thx为答案,但我使用.NET 4.0 – 2014-09-26 14:00:28
你的代码很混乱。你正在使用'WebClient' *和*'HttpWebRequest'。因此,您正在为每个网址提出两个请求。您应该删除'webRequest'和'webResponse',并使用'WebClient'。 – 2014-09-26 16:23:28
很可能你遇到问题的原因是你没有处理你正在创建的'webRequest'和'webResponse'对象。我从经验中知道,这往往会导致事情在几个请求后停止工作。由于您没有使用它们,只需将它们从代码中移除即可。 – 2014-09-26 16:25:09
我只在代码中留下了'Webclient',现在效果很好 – 2014-09-27 15:37:28