diff --git a/Telegrator/Polling/ReactiveUpdateReceiver.cs b/Telegrator/Polling/ReactiveUpdateReceiver.cs
index a4d5b68..4f4cf1f 100644
--- a/Telegrator/Polling/ReactiveUpdateReceiver.cs
+++ b/Telegrator/Polling/ReactiveUpdateReceiver.cs
@@ -1,4 +1,4 @@
-using Telegram.Bot;
+using Telegram.Bot;
using Telegram.Bot.Polling;
using Telegram.Bot.Requests;
using Telegram.Bot.Types;
@@ -7,7 +7,7 @@ namespace Telegrator.Polling
{
///
/// Reactive implementation of for polling updates from Telegram.
- /// Provides custom update receiving logic with error handling and configuration options.
+ /// /// Provides custom update receiving logic with error handling and configuration options.
///
/// The Telegram bot client for making API requests.
/// Optional receiver options for configuring update polling behavior.
@@ -67,7 +67,8 @@ namespace Telegrator.Polling
}
catch (Exception exception2)
{
- await updateHandler.HandleErrorAsync(Client, exception2, HandleErrorSource.HandleUpdateError, cancellationToken).ConfigureAwait(false);
+ await updateHandler.HandleErrorAsync(Client, exception2,
+ HandleErrorSource.HandleUpdateError, cancellationToken).ConfigureAwait(false);
}
}
}
diff --git a/Telegrator/Polling/UpdateHandlersPool.cs b/Telegrator/Polling/UpdateHandlersPool.cs
index 5b3dd49..8b1cbb3 100644
--- a/Telegrator/Polling/UpdateHandlersPool.cs
+++ b/Telegrator/Polling/UpdateHandlersPool.cs
@@ -61,57 +61,72 @@ namespace Telegrator.Polling
///
public async Task Enqueue(IEnumerable handlers)
{
- Result? lastResult = null;
- foreach (DescribedHandlerInfo handlerInfo in handlers)
+ if (ExecutingHandlersSemaphore != null)
{
- if (lastResult?.NextType != null)
- {
- if (lastResult.NextType != handlerInfo.From.HandlerType)
- continue;
- }
-
- if (ExecutingHandlersSemaphore != null)
- {
- await ExecutingHandlersSemaphore.WaitAsync().ConfigureAwait(false);
- }
+ await ExecutingHandlersSemaphore.WaitAsync().ConfigureAwait(false);
+ }
+ // Offload the entire processing of this update's handlers to a background task.
+ // This allows the Receiver to continue polling for NEW updates immediately,
+ // while this update acts as a self-contained unit of work.
+ _ = Task.Run(async () =>
+ {
try
{
- Alligator.LogDebug("Described handler '{0}' (Update {1})", handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
- HandlerExecuting?.Invoke(handlerInfo);
-
- using (UpdateHandlerBase instance = handlerInfo.HandlerInstance)
+ Result? lastResult = null;
+ foreach (DescribedHandlerInfo handlerInfo in handlers)
{
- Task task = instance.Execute(handlerInfo);
- HandlerEnqueued?.Invoke(handlerInfo);
+ if (lastResult?.NextType != null)
+ {
+ if (lastResult.NextType != handlerInfo.From.HandlerType)
+ continue;
+ }
- await task.ConfigureAwait(false);
- lastResult = task.Result;
- ExecutingHandlersSemaphore?.Release(1);
- }
+ try
+ {
+ Alligator.LogDebug("Described handler '{0}' (Update {1})", handlerInfo.DisplayString,
+ handlerInfo.HandlingUpdate.Id);
+ HandlerExecuting?.Invoke(handlerInfo);
- if (lastResult.RouteNext)
- {
- Alligator.LogTrace("Handler '{0}' requested route continuation (Update {1})", handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
+ using (UpdateHandlerBase instance = handlerInfo.HandlerInstance)
+ {
+ Task task = instance.Execute(handlerInfo);
+ HandlerEnqueued?.Invoke(handlerInfo);
+
+ await task.ConfigureAwait(false);
+ lastResult = task.Result;
+ }
+
+ if (lastResult.RouteNext)
+ {
+ Alligator.LogTrace("Handler '{0}' requested route continuation (Update {1})",
+ handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
+ }
+ }
+ catch (NotImplementedException)
+ {
+ _ = 0xBAD + 0xC0DE;
+ }
+ catch (OperationCanceledException)
+ {
+ _ = 0xBAD + 0xC0DE;
+ break;
+ }
+ catch (Exception ex)
+ {
+ Alligator.LogError("Failed to process handler '{0}' (Update {1})", exception: ex,
+ handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
+ }
+
+ if (lastResult != null && !lastResult.RouteNext)
+ break;
}
}
- catch (NotImplementedException)
+ finally
{
- _ = 0xBAD + 0xC0DE;
+ ExecutingHandlersSemaphore?.Release(1);
}
- catch (OperationCanceledException)
- {
- _ = 0xBAD + 0xC0DE;
- break;
- }
- catch (Exception ex)
- {
- Alligator.LogError("Failed to process handler '{0}' (Update {1})", exception: ex, handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
- }
-
- if (lastResult != null && !lastResult.RouteNext)
- break;
- }
+ }, GlobalCancellationToken);
}
///