diff --git a/DTLib.Web/DTLib.Web.csproj b/DTLib.Web/DTLib.Web.csproj index edf821e..75c1a63 100644 --- a/DTLib.Web/DTLib.Web.csproj +++ b/DTLib.Web/DTLib.Web.csproj @@ -2,7 +2,7 @@ DTLib.Web - 1.1.0 + 1.1.1 Timerix HTTP Server with simple routing GIT @@ -25,6 +25,6 @@ - + diff --git a/DTLib.Web/WebApp.cs b/DTLib.Web/WebApp.cs index 1ffb7ab..f8aba8c 100644 --- a/DTLib.Web/WebApp.cs +++ b/DTLib.Web/WebApp.cs @@ -6,6 +6,7 @@ global using System.Threading.Tasks; global using DTLib.Filesystem; global using DTLib.Logging; global using System.Net; +using DTLib.Extensions; using DTLib.Web.Routes; namespace DTLib.Web; @@ -35,7 +36,7 @@ public class WebApp long requestId = 1; while (!_stopToken.IsCancellationRequested) { - var ctx = await server.GetContextAsync(); + var ctx = await server.GetContextAsync().AsCancellable(_stopToken); HandleRequestAsync(ctx, requestId); requestId++; } diff --git a/DTLib/DTLib.csproj b/DTLib/DTLib.csproj index 0a8f4bc..22fa3ba 100644 --- a/DTLib/DTLib.csproj +++ b/DTLib/DTLib.csproj @@ -2,7 +2,7 @@ DTLib - 1.6.3 + 1.6.4 Timerix Library for all my C# projects GIT diff --git a/DTLib/Extensions/TaskExtensions.cs b/DTLib/Extensions/TaskExtensions.cs new file mode 100644 index 0000000..d867693 --- /dev/null +++ b/DTLib/Extensions/TaskExtensions.cs @@ -0,0 +1,37 @@ +namespace DTLib.Extensions; + +public static class TaskExtensions +{ + // https://stackoverflow.com/a/69861689 + public static Task AsCancellable(this Task task, CancellationToken token) + { + if (!token.CanBeCanceled) + { + return task; + } + + var tcs = new TaskCompletionSource(); + // This cancels the returned task: + // 1. If the token has been canceled, it cancels the TCS straightaway + // 2. Otherwise, it attempts to cancel the TCS whenever + // the token indicates cancelled + token.Register(() => tcs.TrySetCanceled(token), + useSynchronizationContext: false); + + task.ContinueWith(t => + { + // Complete the TCS per task status + // If the TCS has been cancelled, this continuation does nothing + if (task.IsCanceled) + tcs.TrySetCanceled(); + else if (task.IsFaulted) + tcs.TrySetException(t.Exception!); + else tcs.TrySetResult(t.Result); + }, + CancellationToken.None, + TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default); + + return tcs.Task; + } +} \ No newline at end of file