我曾经有过:
using (MyWebClient client = new MyWebClient(TimeoutInSeconds))
{
var res = client.DownloadData(par.Base_url);
//code that checks res
}
现在我有:
using (MyWebClient client = new MyWebClient(TimeoutInSeconds))
{
client.DownloadDataAsync(new Uri(par.Base_url));
client.DownloadDataCompleted += (sender, e) =>
{
//code that checks e.Result
}
}
MyWebClient派生自WebClient。 现在我有很多线程在做这个,在第一种情况下,内存消耗不是问题,而在第二种情况下,我看到内存稳定上升,直到我得到OutOfMemoryException。 我描述了似乎WebClient是罪魁祸首,没有被处理和下载数据被保留。但为什么?两种情况有什么区别?也许e.Result需要以某种方式处理?
答案 0 :(得分:2)
您的第一个案例将并发下载的数量限制为线程数。您的第二种情况对并发下载的数量没有限制。
答案 1 :(得分:0)
您正在第二个选项中立即处理WebClient
。你有几个选择:
var res = await client.DownloadDataAsync(par.Base_url);
并且代码看起来与您的第一行类似但实际上是异步的。 using
阻止第一个选项如下:
using (MyWebClient client = new MyWebClient(TimeoutInSeconds))
{
var res = await client.DownloadDataAsync(par.Base_url);
//code that checks res
}
第二个选项如下:
var client = new MyWebClient(TimeoutInSeconds);
client.DownloadDataAsync(new Uri(par.Base_url))
.ContinueWith(t =>
{
client.Dispose();
var res = t.Result;
//code that checks res
}
}
HOWEVER
您必须根据您使用的解决方案更改线程方法。代码的第一个版本是同步运行的,所以如果你有一个专用于URL的线程(或连接,或者你要将它们拆分),下载将在该线程上同步运行并阻止它。但是,如果您选择其中任何一个选项,您将最终使用IO完成线程来完成您的工作,将其从主线程中分离出来。从长远来看,这可能是更好,但这意味着您必须注意并行提交这些请求的数量。