为什么 Socket Accept 需要大约 1 秒才能完成?
Why is Socket Accept taking approx 1 sec to complete?
作为我现在工作的任务的一部分,我需要创建几个 Tcp/Ip 端点。我很惊讶地意识到这太慢了。这是一个代码示例:
var started = new AutoResetEvent(false);
for (int i = 20000; i < 20050; i++)
{
var watch = Stopwatch.StartNew();
started.Reset();
Task.Run(() =>
{
var listener = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp
);
listener.Bind(new IPEndPoint(
IPAddress.Parse("127.0.0.1"), i)
);
listener.Listen(1);
started.Set();
var handler = listener.Accept();
// here goes work after socket is opened
// code omitted for brevity
});
started.WaitOne();
watch.Stop();
Console.WriteLine("Openned in ---> {0}",
watch.ElapsedMilliseconds);
}
这是一个输出示例。
Openned in ---> 73
Openned in ---> 0
Openned in ---> 0
Openned in ---> 570
Openned in ---> 999
Openned in ---> 1000
Openned in ---> 999
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
Openned in ---> 1000
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
作为测试的一部分,预计还没有人连接,这意味着它会在 Accept() 行阻塞。谁能指出发生这种情况的原因?
问题出在您对 Task.Run
的使用上。它不做你认为它做的事。 Task.Run
不创建线程。相反,它在 ThreadPool
上运行。对 "fix" 最简单的更改是使用 Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)
。
然而,使用 async await 更有意义,除非您实际上在 HF space 中工作,这是针对 trading/real 时间定价平台的。那样的话我真的要跟你断绝联系了
你必须增加最小值ThreadPool
By default, the minimum number of threads is set to the number of
processors on a system. You can use the SetMinThreads method to
increase the minimum number of threads. However, unnecessarily
increasing these values can cause performance problems. If too many
tasks start at the same time, all of them might appear to be slow. In
most cases, the thread pool will perform better with its own algorithm
for allocating threads. Reducing the minimum to less than the number
of processors can also hurt performance.
示例;
static void Main(string[] args)
{
ThreadPool.SetMinThreads(100,100);
var started = new AutoResetEvent(false);
//....
作为我现在工作的任务的一部分,我需要创建几个 Tcp/Ip 端点。我很惊讶地意识到这太慢了。这是一个代码示例:
var started = new AutoResetEvent(false);
for (int i = 20000; i < 20050; i++)
{
var watch = Stopwatch.StartNew();
started.Reset();
Task.Run(() =>
{
var listener = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp
);
listener.Bind(new IPEndPoint(
IPAddress.Parse("127.0.0.1"), i)
);
listener.Listen(1);
started.Set();
var handler = listener.Accept();
// here goes work after socket is opened
// code omitted for brevity
});
started.WaitOne();
watch.Stop();
Console.WriteLine("Openned in ---> {0}",
watch.ElapsedMilliseconds);
}
这是一个输出示例。
Openned in ---> 73
Openned in ---> 0
Openned in ---> 0
Openned in ---> 570
Openned in ---> 999
Openned in ---> 1000
Openned in ---> 999
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
Openned in ---> 1000
Openned in ---> 998
Openned in ---> 998
Openned in ---> 1000
作为测试的一部分,预计还没有人连接,这意味着它会在 Accept() 行阻塞。谁能指出发生这种情况的原因?
问题出在您对 Task.Run
的使用上。它不做你认为它做的事。 Task.Run
不创建线程。相反,它在 ThreadPool
上运行。对 "fix" 最简单的更改是使用 Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)
。
然而,使用 async await 更有意义,除非您实际上在 HF space 中工作,这是针对 trading/real 时间定价平台的。那样的话我真的要跟你断绝联系了
你必须增加最小值ThreadPool
By default, the minimum number of threads is set to the number of processors on a system. You can use the SetMinThreads method to increase the minimum number of threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases, the thread pool will perform better with its own algorithm for allocating threads. Reducing the minimum to less than the number of processors can also hurt performance.
示例;
static void Main(string[] args)
{
ThreadPool.SetMinThreads(100,100);
var started = new AutoResetEvent(false);
//....