title: Making an IObservable<T> that uses async/await return completed tasks in original order
body: <p>Suppose you have a list of 100 urls and you want to download them, parse the response and push the results through an IObservable:</p>
  
  <pre><code>public IObservable&lt;ImageSource&gt; GetImages(IEnumerable&lt;string&gt; urls)
  {
      return urls
          .ToObservable()
          .Select(async url =&gt;
          {
              var bytes = await this.DownloadImage(url);
              var image = await this.ParseImage(bytes);
              return image;
          });
  }
  </code></pre>
  
  <p>I have some problems with this. </p>
  
  <p>One is that it's bad etiquette to hammer a server with 100 requests at the same time -- ideally you would rate limit to maybe 6 requests at a given moment. However, if I add a <code>Buffer</code> call, due to the async lambda in <code>Select</code>, everything still fires at the same time.</p>
  
  <p>Moreover, the results will come back in a different order than the input sequence of URLs, which is bad, because the images are part of an animation that will be displayed on the UI.</p>
  
  <p>I've tried all kinds of things, and I have a solution that's working, but it feels convoluted:</p>
  
  <pre><code>public IObservable&lt;ImageSource&gt; GetImages(IEnumerable&lt;string&gt; urls)
  {
      var semaphore = new SemaphoreSlim(6);
  
      return Observable.Create&lt;ImageSource&gt;(async observable =&gt;
      {
          var tasks = urls
              .Select(async url =&gt;
              {
                  await semaphore.WaitAsync();
                  var bytes = await this.DownloadImage(url);
                  var image = await this.ParseImage(url);
              })
              .ToList();
  
          foreach (var task in tasks)
          {
              observable.OnNext(await task);
          }
  
          observable.OnCompleted();
      });
  }
  </code></pre>
  
  <p>It works, but now I'm doing <code>Observable.Create</code> instead of just <code>IObservable.Select</code>, and I have to mess with the semaphore. Also, other animations that run on the UI stop when this is running (they're basically just <code>DispatcherTimer</code> instances), so I think I must be doing something wrong.</p>