title: Azure Event Hubs : QuotaExceededException : 4999 handles limit
body: <p>I am using Azure Event Hub library for C# in WebApi App. And I got this exception on message sending:</p>
  <pre><code>&quot;Message&quot;:&quot;An error has occurred.&quot;,
  &quot;ExceptionMessage&quot;:&quot;Cannot allocate more handles to the current session or connection. The maximum number of handles allowed is 4999. Please free up resources and try again., referenceId: d975f39c71a14ae5915c9adca322e110_G15&quot;
  &quot;ExceptionType&quot;:&quot;Microsoft.ServiceBus.Messaging.QuotaExceededException&quot;
  </code></pre>
  <p>I thought that instantiantion of <code>EventHubProducerClient</code> one time and reusing it instead of creating its instance on each message sending (with <code>IAsyncDisposable</code> pattern) will help as mentioned here
  <a href="https://stackoverflow.com/questions/36836828/eventhub-exception-cannot-allocate-more-handles-to-the-current-session-or-conne">EventHub Exception :Cannot allocate more handles to the current session or connection</a>. But it did not.</p>
  <p>I believe there might be some more global issue. Might be missing something.</p>
  <ul>
  <li>I am using single event hub with 7 consumer groups each of which is used by separate web application (single); well actually there is additional consumer group ($Default) but it is not used;</li>
  <li>For receiving messages I use <code>EventProcessorClient</code>;</li>
  <li>I use <code>Azure.Messaging.EventHubs</code> 5.2.0 and <code>Azure.Messaging.EventHubs.Processor</code> 5.2.0 packages;</li>
  <li>Here is the whole code (did everything according to quickstart):</li>
  </ul>
  <pre><code>    public class EventHubService : SubscriberBase
      {
          private readonly Action&lt;string&gt; errorHandler;
          private readonly BlobContainerClient blobContainerClient;
          private readonly EventProcessorClient eventProcessorClient;
          private readonly EventHubProducerClient eventHubProducerClient;
          private readonly int eventsToCheckpoint;
          private readonly Timer checkpointTimer;
          private int eventsSinceLastCheckpoint;
          private bool shouldUpdateCheckpoint;
  
          public EventHubService(EventHubSettings settings, Action&lt;string&gt; errorHandler) : base()
          {
              this.errorHandler = errorHandler;
              eventHubProducerClient = new EventHubProducerClient(settings.ConnectionString, settings.EventHubName);
  
              if (!String.IsNullOrWhiteSpace(settings.GroupId))
              {
                  eventManager = new EventManager();
  
                  blobContainerClient = new BlobContainerClient(settings.StorageConnectionString, settings.BlobContainerName);
                  eventProcessorClient = new EventProcessorClient(blobContainerClient, settings.GroupId, settings.ConnectionString, settings.EventHubName);
  
                  eventsToCheckpoint = settings.EventsToUpdateCheckpoint;
                  checkpointTimer = new Timer(settings.IntervalToUpdateCheckpoint.TotalMilliseconds);
                  checkpointTimer.Elapsed += (sender, eventArgs) =&gt; shouldUpdateCheckpoint = true;
              }
          }
  
          public override void Start()
          {
              eventProcessorClient.ProcessErrorAsync += HandleError;
              eventProcessorClient.ProcessEventAsync += ProcessEventData;
              eventProcessorClient.StartProcessingAsync().Wait();
              checkpointTimer.Start();
          }
  
          public override async Task Stop()
          {
              try
              {
                  checkpointTimer.Stop();
                  await eventProcessorClient.StopProcessingAsync();
              }
              finally
              {
                  eventProcessorClient.ProcessEventAsync -= ProcessEventData;
                  eventProcessorClient.ProcessErrorAsync -= HandleError;
              }
          }
  
          public override async Task Publish(string topic, JObject message)
          {
              using (EventDataBatch eventBatch = await eventHubProducerClient.CreateBatchAsync())
              {
                  var @event = new Event(topic, message);
                  string json = @event.ToString(Formatting.None);
                  byte[] bytes = Encoding.UTF8.GetBytes(json);
                  var eventData = new EventData(bytes);
                  eventBatch.TryAdd(eventData);
  
                  await eventHubProducerClient.SendAsync(eventBatch);
              }
          }
  
          private async Task ProcessEventData(ProcessEventArgs eventArgs)
          {
              if (eventArgs.CancellationToken.IsCancellationRequested)
              {
                  return;
              }
  
              if (++eventsSinceLastCheckpoint &gt;= eventsToCheckpoint)
              {
                  eventsSinceLastCheckpoint = 0;
                  shouldUpdateCheckpoint = true;
              }
  
              if (shouldUpdateCheckpoint)
              {
                  await eventArgs.UpdateCheckpointAsync();
                  shouldUpdateCheckpoint = false;
              }
  
              string json = Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray());
              var @event = new Event(json);
              eventManager.TryRaise(@event);
          }
  
          private Task HandleError(ProcessErrorEventArgs eventArgs)
          {
              if (!eventArgs.CancellationToken.IsCancellationRequested)
              {
                  errorHandler.Invoke($&quot;[P:{eventArgs.PartitionId}][O:{eventArgs.Operation}] {eventArgs.Exception.Message}&quot;);
              }
  
              return Task.CompletedTask;
          }
      }  
  </code></pre>
  <p>I have found some info in <a href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas" rel="nofollow noreferrer">Service Bus Quotas</a> like:</p>
  <blockquote>
  <p>Number of concurrent receive requests on a queue, topic, or subscription entity (5000).</p>
  <p>Subsequent receive requests are rejected, and an exception is received
  by the calling code. This quota applies to the combined number
  of concurrent receive operations across all subscriptions on a topic.</p>
  </blockquote>
  <p>But still can't figure how to deal with it.</p>
  <p>Please help.
  Thanks.</p>