title: Reading from multiple WebSockets with async/await
body: <p>I'm writing a .NET Core Console App that needs to continuously read data from multiple WebSockets. My current approach is to create a new Task (via Task.Run) per WebSocket that runs an infinite while loop and blocks until it reads the data from the socket. However, since the data is pushed at a rather low frequency, the threads just block most of the time which seems quite inefficient.</p>
  
  <p>From my understanding, the async/await pattern should be ideal for blocking I/O operations. However, I'm not sure how to apply it for my situation or even if async/await can improve this in any way - especially since it's a Console app. </p>
  
  <p>I've put together a proof of concept (doing a HTTP GET instead of reading from WebSocket for simplicity). The only way I was able to achieve this was without actually awaiting. Code:</p>
  
  <pre><code>static void Main(string[] args)
  {
      Console.WriteLine($"ThreadId={ThreadId}: Main");
  
      Task task = Task.Run(() =&gt; Process("https://duckduckgo.com", "https://stackoverflow.com/"));
  
      // Do main work.
  
      task.Wait();
  }
  
  private static void Process(params string[] urls)
  {
      Dictionary&lt;string, Task&lt;string&gt;&gt; tasks = urls.ToDictionary(x =&gt; x, x =&gt; (Task&lt;string&gt;)null);
      HttpClient client = new HttpClient();
  
      while (true)
      {
          foreach (string url in urls)
          {
              Task&lt;string&gt; task = tasks[url];
              if (task == null || task.IsCompleted)
              {
                  if (task != null)
                  {
                      string result = task.Result;
                      Console.WriteLine($"ThreadId={ThreadId}: Length={result.Length}");
                  }
                  tasks[url] = ReadString(client, url);
              }
          }
          Thread.Yield();
      }
  }
  
  private static async Task&lt;string&gt; ReadString(HttpClient client, string url)
  {
      var response = await client.GetAsync(url);
      Console.WriteLine($"ThreadId={ThreadId}: Url={url}");
      return await response.Content.ReadAsStringAsync();
  }
  
  private static int ThreadId =&gt; Thread.CurrentThread.ManagedThreadId;
  </code></pre>
  
  <p>This seems to be working and executing on various Worker Threads on the ThreadPool. However, this definitely doesn't seem as any typical async/await code which makes me think there has to be a better way.</p>
  
  <p><strong>Is there a more proper / more elegant way of doing this?</strong></p>