Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET多线程Web请求_C#_Asp.net_Multithreading_Webrequest - Fatal编程技术网

C# ASP.NET多线程Web请求

C# ASP.NET多线程Web请求,c#,asp.net,multithreading,webrequest,C#,Asp.net,Multithreading,Webrequest,我正在ASP.NET解决方案中构建一个页面,该页面从第三方API服务检索其大部分数据 页面本身需要对API进行大约5次不同的调用,以填充其所有控件,因为对API的每个Web请求都会返回不同的数据集 我想在一个新线程上同时处理每个单独的Web请求,以减少加载时间 我提出的每个请求如下所示:- WebRequest request = WebRequest.Create(requestUrl); string response = new StreamReader(request.GetRespo

我正在ASP.NET解决方案中构建一个页面,该页面从第三方API服务检索其大部分数据

页面本身需要对API进行大约5次不同的调用,以填充其所有控件,因为对API的每个Web请求都会返回不同的数据集

我想在一个新线程上同时处理每个单独的Web请求,以减少加载时间

我提出的每个请求如下所示:-

WebRequest request = WebRequest.Create(requestUrl);

string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();

return new JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
WebRequest-request=WebRequest.Create(requestUrl);
字符串响应=新的StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
返回新的JsonSerializer()。反序列化(新的JSONtexReader(新的StringReader(响应));
首先,我应该尝试一下吗?i、 e,安全吗?它将通过多线程来提高性能


第二,做这件事的最佳方式是什么?多线程系统有许多不同的方式,但哪种方式最适合此任务?

我认为多线程(合理)将提供好处,因为您的代码编写方式知道对GetResponse()的调用。GetResponseStream()被阻塞

提高性能的最简单方法之一是使用:

var url=newlist();
var结果=新的ConcurrentBag();
Parallel.ForEach(url,url=>
{
WebRequest=WebRequest.Create(requestUrl);
字符串响应=新的StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var result=JsonSerializer()。反序列化(新的JsonTextReader(新的StringReader(响应));
结果。添加(结果);
});
如果您使用的是.NET4.5,那么新的方法是使用async/await。Msdn在这里有一篇关于这个主题的非常广泛的文章:和


Scott Hanselman在这个主题上也有一篇很好看的博文:

多线程是正确的选择,但我称之为异步执行

无论如何,您应该知道多线程在IIS中的工作方式不同

一旦所有子线程结束,IIS工作进程将完成一个请求,这是一个大问题,因为您不希望长时间保留一个工作进程,而是将其重新用于其他请求。实际上这是一个线程池

这就是为什么ASP.NET提供了自己的实现异步的方法,如果使用正确的方法,IIS将能够一次处理更多请求,因为异步工作将在IIS进程模型之外执行

我建议您阅读有关ASP.NET async的更多信息:

结论:使用异步工作,这将更有效地利用服务器资源,但首先要了解如何以正确的方式完成它

不建议在ASP.NET上使用多线程;因为ASP.NET/IIS有自己的多线程处理,您所做的任何多线程处理都会干扰这些启发式

您真正想要的是并发,更具体地说是异步并发,因为您的操作是I/O绑定的

最好的方法是将
HttpClient
与以下组件一起使用:


每个web请求都应该是IIS中不同的工作线程,具体取决于您的服务负载以及IIS的设置方式。因此,如果您谈论多线程,您将尝试将每个请求完成的工作细分为多个线程。我将研究异步执行。使用
request.GetResponseAsync()
等。由于
List
不是线程安全的(用于写入),您不需要
lock(results)
吗?公平地说,老实说,我不确定列表是否会丢失任何东西,因为它没有读取和写入。但为了安全起见,我将更新以使用ConcurrentBag。列表正在写入-它正在写入结果的
添加
。你只需要在它周围加一个
锁就行了。谢谢你的建议。@Derek,没问题。事实上,你应该走这条路,因为其他方法会以死锁告终。谢谢你的建议
        var urls = new List<string>();

        var results = new ConcurrentBag<OccupationSearch>();

        Parallel.ForEach(urls, url =>
        {
            WebRequest request = WebRequest.Create(requestUrl);

            string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();

            var result = JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));

            results.Add(result);
        });
public async Task<OccupationSearch> GetOccupationAsync(string requestUrl)
{
  // You can also reuse HttpClient instances instead of creating a new one each time
  using (var client = new HttpClient())
  {
    var response = client.GetStringAsync(requestUrl);
    return new JsonSerializer().Deserialize<OccupationSearch>(new JsonTextReader(new StringReader(response)));
  }
}
List<string> urls = ...;
OccupationSearch[] results = await Task.WhenAll(urls.Select(GetOccupationAsync));