title: MongoDB Client throws Wait Queue Full exception
body: <p>I am seeing an odd issue where The .NET client for MongoDB throws a <code>The wait queue for acquiring a connection to server 127.0.0.1:27017 is full.</code> exception.</p>
  <p>I have a semaphore that guards any call to MongoDB, with a size of 10.
  Meaning, there are never more than 10 concurrent calls to Mongo.</p>
  <p>The default connection pool size is 100 for the .NET driver, which is more than 10.
  so 10 concurrent calls should not be an issue.</p>
  <p>To replicate this I have the following code, contrived yes, but it makes the issue visible.</p>
  <p>I also found this spec for MongoDB
  <a href="https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst#id94" rel="nofollow noreferrer">https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst#id94</a></p>
  <p>Is that related?
  Does each calling thread (thread pool worker in this case) go into the wait queue and try to grab a connection, and if I have more worker threads, even if concurrency level is low, the connections still have to be assigned to this new calling worker thread?</p>
  <pre><code>using System;
  using System.Threading.Tasks;
  using MongoDB.Bson;
  using MongoDB.Driver;
  using System.Threading;
  
  namespace ConsoleApp58
  {
      public class AsyncSemaphore
      {
          private readonly SemaphoreSlim _semaphore;
  
          public AsyncSemaphore(int maxConcurrency)
          {
              _semaphore = new SemaphoreSlim(
                  maxConcurrency,
                  maxConcurrency
              );
          }
  
          public async Task&lt;T&gt; WaitAsync&lt;T&gt;(Task&lt;T&gt; task)
          {
              await _semaphore.WaitAsync();
              //proves we have the correct max concurrent calls
              //  Console.WriteLine(_semaphore.CurrentCount);
  
              try
              {
                  var result = await task;
                  return result;
              }
              finally
              {
                  _semaphore.Release();
              }
          }
      }
      
      class Program
      {
          public class SomeEntity
          {
              public ObjectId Id { get; set; }
              public string Name { get; set; }
          }
  
          static void Main(string[] args)
          {
              var settings = MongoClientSettings.FromUrl(MongoUrl.Create(&quot;mongodb://127.0.0.1:27017&quot;));
              // settings.MinConnectionPoolSize = 10;
              // settings.MaxConnectionPoolSize = 1000;
              
              // I get that I can tweak settings, but I want to know why this occurs at all?
              // if we guard the calls with a semaphore, how can this happen?
  
              var mongoClient = new MongoClient(settings);
              var someCollection = mongoClient.GetDatabase(&quot;dummydb&quot;).GetCollection&lt;SomeEntity&gt;(&quot;some&quot;);
              var a = new AsyncSemaphore(10);
              
              // is this somehow related ?
              // https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst#id94
  
  
              _ = Task.Run(() =&gt;
                  {
                      while (true)
                      {
                          // this bit is protected by a semaphore of size 10
                          // (we will flood the thread pool with ongoing tasks, yes)
                          _ = a.WaitAsync(RunTask(someCollection))
                              //after the task is done, dump the result
                              // dot is OK, else exception message
                              .ContinueWith(x =&gt;
                              {
                                  if (x.IsFaulted)
                                  {
                                      Console.WriteLine(x.Exception);
                                  }
                              });
                      }
                  }
              );
  
              Console.ReadLine();
          }
  
          private static async Task&lt;SomeEntity&gt; RunTask(IMongoCollection&lt;SomeEntity&gt; pids)
          {
              //simulate some mongo interaction here
              var res = await pids.Find(x =&gt; x.Name == &quot;&quot;).FirstOrDefaultAsync();
              return res;
          }
      }
  }
  </code></pre>