[英].NET Core: Concurrency defect in WebClient?
我使用這段代碼來敲擊系統:
WebClient client = new WebClient();
int i = 0;
int limit = 10000;
long start = DateTime.Now.Ticks;
do
{
Console.WriteLine($"{DateTime.Now:h:mm:ss.fffffff} : " + ++i);
client.DownloadString("https://localhost:44305/");
} while (i < limit);
Console.WriteLine(limit + " requests in " + new TimeSpan(DateTime.Now.Ticks - start) + " (" + ((DateTime.Now.Ticks - start)/limit)/1000 + " ms/request)");
有時它會起作用。 有時我會遇到異常(迭代次數似乎是隨機的):
System.Net.WebException: Only one usage of each socket address (protocol/network address/port) is normally permitted. Only one usage of each socket address (protocol/n
etwork address/port) is normally permitted.
---> System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
---> System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted.
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at System.Net.HttpWebRequest.SendRequest()
at System.Net.HttpWebRequest.GetResponse()
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at System.Net.WebClient.GetWebResponse(WebRequest request)
at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream)
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
at System.Net.WebClient.DownloadString(Uri address)
at CommandName.ThingDoer.DoThing(IRepository repository) in C:\data\OneDrive\source\rider\ContentstackPlaygroundTemplates\cstest\ThingDoer.cs:line 31
at CommandName.Program.<>c__DisplayClass0_1.<Main>b__0() in C:\data\OneDrive\source\rider\ContentstackPlaygroundTemplates\cstest\Program.cs:line 65
at McMaster.Extensions.CommandLineUtils.CommandLineApplicationExtensions.<>c__DisplayClass9_0.<OnExecute>b__0()
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.<>c__DisplayClass144_0.<OnExecute>b__0(CancellationToken _)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at CommandName.Program.Main(String[] args) in C:\data\OneDrive\source\rider\ContentstackPlaygroundTemplates\cstest\Program.cs:line 70 : Only one usage of each socket address (protocol/network address/port) is normally permitted. Only one usage of each socket address (protocol/network address/port) is normally permitted.
這可能是 WebClient 中的並發缺陷,我做錯了什么,或者可能是什么解釋?
System.Web.Client 4.0.2.0,.NETCoreApp v3.0.3
謝謝你。 我沒有嘗試使用 ServicePointManager,因為 HttpClient 似乎解決了這個問題。 這似乎現在有效。
private void McHammer()
{
int i = 0;
int limit = 1000;
DateTime start = DateTime.Now;
HttpClient httpClient = new HttpClient();
do
{
try
{
if (i % 100 == 0)
{
Console.Write("#");
}
string discard = httpClient.GetStringAsync("https://localhost:5001/").Result;
}
catch (HttpRequestException ex)
{
Console.WriteLine(ex.GetType() + " : " + ex.Message);
// break on first error
limit = 0;
}
} while (i++ < limit);
TimeSpan timeSpan = new TimeSpan(DateTime.Now.Ticks - start.Ticks);
double ms = timeSpan.Ticks / 10000;
double msPerRequest = ms / --i;
double requestPerSec = i / ms;
Console.WriteLine(
"{0} : {1} requests in {2}ms ({3} ~ms/request; ~{4} request/sec)",
this,
i,
ms,
Math.Round(msPerRequest * 1000)/1000,
Math.Round(requestPerSec * 1000));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.