2015-08-06 3 views
0

В рамках задачи, которую я сейчас работаю, мне нужно создать несколько конечных точек Tcp/Ip. Я был удивлен, осознав, что это так медленно. Ниже приведен пример кода:Почему Socket Accept занимает около 1 секунды?

 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(). Кто может указать мне, почему это происходит?

+0

Что вы делаете в пропущенном коде? – Fredou

+0

@Fredou пропущенный код передает 'handler' другому thred – ruslander

+0

Почему бы вам не использовать' Task.Run' ?! – Aron

ответ

1

Проблема возникает из-за использования Task.Run. Он не делает то, что, по вашему мнению, делает. Task.Run не создает поток. Вместо этого он работает на ThreadPool. Самое простое изменение «исправить» это вместо этого использовать Task.Factory.StartNew(..., TaskCreationOptions.LongRunning).

Однако имеет смысл сделать так, чтобы использование async ожидало, если только вы на самом деле не работаете в пространстве HF, и это относится к платформе ценообразования для торговли/реального времени. В этом случае мне действительно нужно прекратить общение с вами.

+0

он будет открытым исходным кодом сейчас I am прототипирование, 'TaskCreationOptions.LongRunning' сделал трюк, спасибо – ruslander

0

вы должны увеличить минимальный ThreadPool

По умолчанию минимальное число потоков устанавливается на число процессоров системы. Вы можете использовать метод SetMinThreads для , чтобы увеличить минимальное количество потоков. Однако излишне Увеличение этих значений может привести к проблемам с производительностью. Если слишком много задач запускаются одновременно, все они могут казаться медленными. В большинстве случаев пул потоков будет работать лучше с собственным алгоритмом для распределения потоков. Уменьшение минимального числа до процессоров также может повредить производительность.

пример;

static void Main(string[] args) 
    { 
     ThreadPool.SetMinThreads(100,100); 

     var started = new AutoResetEvent(false); 

     //.... 
Смежные вопросы