title: Azure.Messaging.ServiceBus Error when completing or abandoning message
body: <p>Som I'm currently looking into updating our very simple service bus service to the latest version (Asure.Messaging.Servicebus) and I'm running into a smaller problem here.</p>
  <p>The thing is I want to complete or abandon received or peaked messages manually by delegating the message back to methods in my service class to handle the job.</p>
  <p>Here is my simple class so far, exposed by an interface.</p>
  <pre class="lang-cs prettyprint-override"><code>using myProject.Interfaces;
  using myProject.Utilities;
  using Azure.Messaging.ServiceBus;
  using System;
  
  namespace myProject.Services
  {
      /// &lt;summary&gt;
      /// Service bus service controller
      /// &lt;/summary&gt;
      public class ServiceBusService: IServiceBusService
      {
          private IConfigurationUtility _configurationUtility;
          static string connectionString;
          static ServiceBusClient client;
          static ServiceBusSender sender;
          static ServiceBusReceiver receiver;
  
          public ServiceBusService(IConfigurationUtility configurationUtility)
          {
              _configurationUtility = configurationUtility;
              connectionString = _configurationUtility.GetSetting(&quot;ServiceBusConnectionString&quot;);
              client = new ServiceBusClient(connectionString);
          }
  
          /// &lt;summary&gt;
          /// Sending message.
          /// &lt;/summary&gt;
          /// &lt;param name=&quot;messageContent&quot;&gt;&lt;/param&gt;
          /// &lt;param name=&quot;queueName&quot;&gt;&lt;/param&gt;
          public void SendMessage(string messageContent, string queueName)
          {
              sender = client.CreateSender(queueName);
              ServiceBusMessage message = new ServiceBusMessage(messageContent);
              sender.SendMessageAsync(message).Wait();
          }
  
          /// &lt;summary&gt;
          /// Receive message.
          /// &lt;/summary&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          /// &lt;param name=&quot;queueName&quot;&gt;&lt;/param&gt;
          public ServiceBusReceivedMessage ReceiveMessage(string queueName)
          {
  
              receiver = client.CreateReceiver(queueName);
              ServiceBusReceivedMessage receivedMessage = receiver.ReceiveMessageAsync().Result;
              return receivedMessage;
          }
  
          /// &lt;summary&gt;
          /// Peek message.
          /// &lt;/summary&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public ServiceBusReceivedMessage PeekMessage(string queueName)
          {
              receiver = client.CreateReceiver(queueName);
              ServiceBusReceivedMessage peekedMessage = receiver.PeekMessageAsync().Result;
              return peekedMessage;
          }
  
          /// &lt;summary&gt;
          /// Complete message.
          /// &lt;/summary&gt;
          /// &lt;param name=&quot;message&quot;&gt;&lt;/param&gt;
          public void CompleteMessage(ServiceBusReceivedMessage message)
          {
              receiver.CompleteMessageAsync(message).Wait();
          }
  
          /// &lt;summary&gt;
          /// Abandon message.
          /// &lt;/summary&gt;
          /// &lt;param name=&quot;message&quot;&gt;&lt;/param&gt;
          public void AbandonMessage(ServiceBusReceivedMessage message)
          {
              receiver.AbandonMessageAsync(message).Wait();
          }
      }
  }
  </code></pre>
  <p>everything works well when I'm handling one message at a time, but if I would process two messages at a time for example I get this error:</p>
  <blockquote>
  <p>&quot;The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance&quot;</p>
  </blockquote>
  <p>And I think the <em>&quot;or was received by a different receiver instance&quot;</em> part is my problem.</p>
  <p>Am I thinking about this the wrong way? shouldn't I be able to handle for example: abandoning multiple <em>single</em> received messages at a time?</p>
  <p>Thanks in advance.</p>
  <p><strong>UPDATE:</strong></p>
  <p>So i think i managed to get it working in regards to what Jesse Squire have been suggested to do in reflection to the new Servicebus ducumentation provided by microsoft.</p>
  <p>I Made a new class called ServicebusFactory, added the code provided by Jesse below, to test it out and changed the &quot;<em>= new();</em>&quot; part for the initialized &quot;<em>ConcurrentDictionary's</em>&quot; at the top of the example, as initializing them like this resulted in the error below:</p>
  <blockquote>
  <p>CS8400    Feature 'target-typed object creation' is not available in C# 8.0. Please use language version 9.0 or greater.</p>
  </blockquote>
  <p>Result:</p>
  <pre class="lang-cs prettyprint-override"><code>    public class ServiceBusFactory : IAsyncDisposable, IServiceBusFactory
      {
          private readonly ServiceBusClient _client;
          private readonly ConcurrentDictionary&lt;string, ServiceBusSender&gt; _senders = new ConcurrentDictionary&lt;string, ServiceBusSender&gt;();
          private readonly ConcurrentDictionary&lt;string, ServiceBusReceiver&gt; _receivers = new ConcurrentDictionary&lt;string, ServiceBusReceiver&gt;();
  
          public ServiceBusFactory(string fullyQualifiedNamespace, TokenCredential credential) =&gt; _client = new ServiceBusClient(fullyQualifiedNamespace, credential);
          public ServiceBusFactory(string connectionString) =&gt; _client = new ServiceBusClient(connectionString);
  
          public ServiceBusSender GetSender(string entity) =&gt;
              _senders.GetOrAdd(entity, entity =&gt; _client.CreateSender(entity));
  
          public ServiceBusReceiver GetReceiver(string entity) =&gt;
              _receivers.GetOrAdd(entity, entity =&gt; _client.CreateReceiver(entity));
  
          public async ValueTask DisposeAsync()
          {
              await _client.DisposeAsync().ConfigureAwait(false);
              GC.SuppressFinalize(this);
          }
      }
  }
  </code></pre>
  <p>I then created an interface for my service bus factory and added this as a singelton to the bottom of my &quot;<em>ConfigurationService</em>&quot; method in my &quot;<em>Startup.cs</em>&quot; class, initializing it with my service bus connection string.</p>
  <p>Interface:</p>
  <pre class="lang-cs prettyprint-override"><code>public interface IServiceBusFactory
  {
     public ServiceBusSender GetSender(string entity);
  
     public ServiceBusReceiver GetReceiver(string entity);
  
     public ValueTask DisposeAsync();
  }
  </code></pre>
  <p>Startup:</p>
  <pre class="lang-cs prettyprint-override"><code>var serviceBusConnectionString = &quot;[CONNECTION STRING]&quot;;
  services.AddSingleton&lt;IServiceBusFactory&gt;(new ServiceBusFactory(serviceBusConnectionString));
  </code></pre>
  <p>Finally it was a matter of dependency inject the servicebusFactory interface to my controller constructor and then use it to get a &quot;<em>sender</em>&quot; and using it to send a message to my queue called &quot;<em>Add</em>&quot;.</p>
  <p>Constructor:</p>
  <pre class="lang-cs prettyprint-override"><code>private readonly IServiceBusFactory _serviceBusFactory;
  
  public ServicebusController(IServiceBusFactory serviceBusFactory) 
  {
      _serviceBusFactory = serviceBusFactory; 
  }
  </code></pre>
  <p>Controller Method/Action implementation:</p>
  <pre class="lang-cs prettyprint-override"><code>var test = new List&lt;ServiceBusMessage&gt;();
  test.Add(new ServiceBusMessage(&quot;This is a test message.&quot;));
  
  var sender = _serviceBusFactory.GetSender(&quot;Add&quot;);
  sender.SendMessagesAsync(test);
  </code></pre>