2014-10-30 6 views
6

Я не совсем 'get' async и жду еще, и я ищу некоторые разъяснения вокруг конкретной проблемы, которую я собираюсь решить. В принципе, мне нужно написать код, который будет обрабатывать TCP-соединение. По сути, он просто получает данные и обрабатывает их до тех пор, пока соединение не будет закрыто.async/await vs BeginRead, EndRead

Обычно я пишу этот код, используя шаблон NetworkStream BeginRead и EndRead, но поскольку шаблон async/await намного чище, у меня возникает соблазн использовать его. Однако, поскольку я, по общему признанию, не совсем точно понимаю, что в них участвует, я немного опасаюсь последствий. Будет ли использовать больше ресурсов, чем другой; будет использоваться нить, где другой будет использовать IOCP и т. д.

Время свернутого примера. Эти два делают то же самое - считать байты в потоке:

class StreamCount 
{ 
    private Stream str; 
    private int total = 0; 
    private byte[] buffer = new byte[1000]; 

    public Task<int> CountBytes(Stream str) 
    { 
     this.str = str; 

     var tcs = new TaskCompletionSource<int>(); 
     Action onComplete =() => tcs.SetResult(total); 
     str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, onComplete); 

     return tcs.Task; 
    } 

    private void BeginReadCallback(IAsyncResult ar) 
    { 
     var bytesRead = str.EndRead(ar); 
     if (bytesRead == 0) 
     { 
      ((Action)ar.AsyncState)(); 
     } 
     else 
     { 
      total += bytesRead; 
      str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, ar.AsyncState); 
     } 
    } 
} 

... И ...

public static async Task<int> CountBytes(Stream str) 
    { 
     var buffer = new byte[1000]; 
     var total = 0; 
     while (true) 
     { 
      int bytesRead = await str.ReadAsync(buffer, 0, 1000); 
      if (bytesRead == 0) 
      { 
       break; 
      } 
      total += bytesRead; 
     } 
     return total; 
    } 

К моим глазам, Асинхронный способ выглядит чище, но есть то, что ' while (true) ', который мой необразованный мозг говорит мне, будет использовать лишнюю нить, больше ресурсов и, следовательно, не будет масштабироваться, как и другой. Но я уверен, что это неправильно. То же ли они делают одно и то же?

ответ

7

На мой взгляд, асинхронный способ выглядит более чистым, но есть цикл «while (true)», который мой необразованный мозг говорит мне, что он будет использовать дополнительную нить, больше ресурсов и, следовательно, не будет масштабироваться а также другой.

Нет, это не так. Цикл будет только использовать поток, когда он на самом деле работает код ... точно так же, как в вашем BeginRead обратном вызове. Выражение await будет возвращать управление ко всему вызывающему коду, зарегистрировав продолжение, которое возвращается в нужное место в методе (в соответствующем потоке на основе контекста синхронизации), а затем продолжает работать до тех пор, пока оно не дойдет до конца метода или использует другое выражение await. Это именно то, что вы хотите :)

Необходимо узнать больше о том, как асинхронный/ждущий работает за кулисами - вы можете начать с the MSDN page on it в качестве прыгающей точки.

+0

Это полезно знать! Действительно полезно. Я также дам страницу MSDN. Я думаю, что блок-схемы пугали меня раньше, но я буду храбр! :) [будет принимать, когда смогу] – Barguast

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

  • Нет связанных вопросов^_^