diff --git a/readme.md b/readme.md index 0e72058..1222d9d 100644 --- a/readme.md +++ b/readme.md @@ -7,13 +7,11 @@ NuGet package: https://www.nuget.org/packages/ContextFreeTasks/ Use `ContextFreeTask` struct instead of `Task` class (`System.Threading.Tasks` namespace) for return types of async methods. ```csharp -private async ContextFreeTask FAsync() -{ - ... -} +private async ContextFreeTask FAsync() { ... } +private async ContextFreeTask FAsync() { ... } ``` -This ignores the current synchronization context. +These ignore the current synchronization context in the methods. You do not have to write `ConfigureAwait(false)` anymore. ### Task-like @@ -25,11 +23,7 @@ The `ContextFreeTask` struct in this library satisfies the "Task-like" pattern a ### What ContextFreeTask does -This struct ignores synchronization context at all. -In other words, - -- `await` operations in the methods which return `ContextFreeTask` capture no context -- `await` operations on `ContextFreeTask` capture no context +The methods which return `ContextFreeTask` do not capture the synchronization context. For example, you can use this as following: @@ -43,14 +37,6 @@ private async ContextFreeTask FAsync() await Task.Delay(100); // no context here } - -private async Task GAsync() -{ - // You can await on ContextFreeTask - // ContextFreeTask don't capture current context - await FAsync(); - // no context here -} ``` This code behaves almost the same as the following: @@ -61,11 +47,6 @@ private async Task FAsync() await Task.Delay(100).ConfigureAwait(false); await Task.Delay(100).ConfigureAwait(false); } - -private async Task GAsync() -{ - await FAsync().ConfigureAwait(false); -} ``` ### Implementation @@ -88,17 +69,7 @@ public struct ContextFreeTask } ``` -Those awaiters always use `ConfigureAwait(false)`. - -```cs -public struct ContextFreeTaskAwaiter : ICriticalNotifyCompletion -{ - private readonly Task _value; - public void OnCompleted(Action continuation) => _value.ConfigureAwait(false).GetAwaiter().OnCompleted(continuation); -} -``` - -Furthermore, those AsyncMethodBuilders always clear current synchronization context. +Those AsyncMethodBuilders always clear current synchronization context. ```cs public struct AsyncContextFreeTaskMethodBuilder diff --git a/src/ContextFreeTasks.Shared/ContextFreeTask.cs b/src/ContextFreeTasks.Shared/ContextFreeTask.cs index 710d5fd..ee5a0cf 100644 --- a/src/ContextFreeTasks.Shared/ContextFreeTask.cs +++ b/src/ContextFreeTasks.Shared/ContextFreeTask.cs @@ -11,7 +11,7 @@ public struct ContextFreeTask private readonly Task _task; public Task Task => _task ?? FromResult(default(object)); internal ContextFreeTask(Task t) => _task = t; - public ContextFreeTaskAwaiter GetAwaiter() => new ContextFreeTaskAwaiter(Task); + public TaskAwaiter GetAwaiter() => Task.GetAwaiter(); public void Wait() => _task?.Wait(); public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) => Task.ConfigureAwait(continueOnCapturedContext); } diff --git a/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter.cs b/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter.cs deleted file mode 100644 index 947d97e..0000000 --- a/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -namespace ContextFreeTasks.Internal -{ - public struct ContextFreeTaskAwaiter : ICriticalNotifyCompletion - { - private readonly Task _value; - internal ContextFreeTaskAwaiter(Task value) => _value = value; - public bool IsCompleted => _value.IsCompleted; - public void GetResult() => _value.GetAwaiter().GetResult(); - public void OnCompleted(Action continuation) => _value.ConfigureAwait(false).GetAwaiter().OnCompleted(continuation); - public void UnsafeOnCompleted(Action continuation) => _value.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(continuation); - } -} diff --git a/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter_T.cs b/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter_T.cs deleted file mode 100644 index 2d6410d..0000000 --- a/src/ContextFreeTasks.Shared/ContextFreeTaskAwaiter_T.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -namespace ContextFreeTasks.Internal -{ - public struct ContextFreeTaskAwaiter : ICriticalNotifyCompletion - { - private readonly Task _value; - internal ContextFreeTaskAwaiter(Task value) => _value = value; - public bool IsCompleted => _value.IsCompleted; - public T GetResult() => _value.GetAwaiter().GetResult(); - public void OnCompleted(Action continuation) => _value.ConfigureAwait(false).GetAwaiter().OnCompleted(continuation); - public void UnsafeOnCompleted(Action continuation) => _value.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(continuation); - } -} diff --git a/src/ContextFreeTasks.Shared/ContextFreeTask_T.cs b/src/ContextFreeTasks.Shared/ContextFreeTask_T.cs index e85ac18..bee34ed 100644 --- a/src/ContextFreeTasks.Shared/ContextFreeTask_T.cs +++ b/src/ContextFreeTasks.Shared/ContextFreeTask_T.cs @@ -12,7 +12,7 @@ public struct ContextFreeTask public Task Task => _task ?? FromResult(default(T)); public T Result => GetAwaiter().GetResult(); internal ContextFreeTask(Task t) => _task = t; - public ContextFreeTaskAwaiter GetAwaiter() => new ContextFreeTaskAwaiter(Task); + public TaskAwaiter GetAwaiter() => Task.GetAwaiter(); public void Wait() => _task?.Wait(); public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) => Task.ConfigureAwait(continueOnCapturedContext); } diff --git a/src/ContextFreeTasks.Shared/ContextFreeTasks.Shared.projitems b/src/ContextFreeTasks.Shared/ContextFreeTasks.Shared.projitems index d132c49..93822a5 100644 --- a/src/ContextFreeTasks.Shared/ContextFreeTasks.Shared.projitems +++ b/src/ContextFreeTasks.Shared/ContextFreeTasks.Shared.projitems @@ -9,12 +9,14 @@ ContextFreeTasks - - - + + + - - + + + + \ No newline at end of file diff --git a/src/ContextFreeTasks.Shared/AsyncContextFreeTaskMethodBuilder.cs b/src/ContextFreeTasks.Shared/Internal/AsyncContextFreeTaskMethodBuilder.cs similarity index 100% rename from src/ContextFreeTasks.Shared/AsyncContextFreeTaskMethodBuilder.cs rename to src/ContextFreeTasks.Shared/Internal/AsyncContextFreeTaskMethodBuilder.cs diff --git a/src/ContextFreeTasks.Shared/AsyncContextFreeTaskMethodBuilder_T.cs b/src/ContextFreeTasks.Shared/Internal/AsyncContextFreeTaskMethodBuilder_T.cs similarity index 100% rename from src/ContextFreeTasks.Shared/AsyncContextFreeTaskMethodBuilder_T.cs rename to src/ContextFreeTasks.Shared/Internal/AsyncContextFreeTaskMethodBuilder_T.cs diff --git a/src/ContextFreeTasks.Shared/AsyncMethodBuilderAttribute.cs b/src/ContextFreeTasks.Shared/System.Runtime.CompilerServices/AsyncMethodBuilderAttribute.cs similarity index 100% rename from src/ContextFreeTasks.Shared/AsyncMethodBuilderAttribute.cs rename to src/ContextFreeTasks.Shared/System.Runtime.CompilerServices/AsyncMethodBuilderAttribute.cs diff --git a/src/ContextFreeTasks.nuspec b/src/ContextFreeTasks.nuspec index f14115a..6f11fc2 100644 --- a/src/ContextFreeTasks.nuspec +++ b/src/ContextFreeTasks.nuspec @@ -2,7 +2,7 @@ ContextFreeTasks - 0.2.0 + 0.3.0 ContextFreeTasks Nobuyuki Iwanaga Nobuyuki Iwanaga @@ -10,9 +10,9 @@ https://github.com/ufcpp/ContextFreeTask/ false Task-like structs which capture no synchronization context on the await operations in C# - Add and change some methods for consistency with the Task and the ValueTask + remove context-free awaiters. ContextFreeTask provides only context-free method-builders. Nobuyuki Iwanaga - Task-like, async method, ConfigureAwait, SynchronizationContext + Task-like, async method, ConfigureAwait, SynchronizationContext, AsynchMethodBuilder diff --git a/tests/UnitTestNet45/UnitTest1.cs b/tests/UnitTestNet45/UnitTest1.cs index e1c5b07..da7eb0f 100644 --- a/tests/UnitTestNet45/UnitTest1.cs +++ b/tests/UnitTestNet45/UnitTest1.cs @@ -55,11 +55,11 @@ private async Task A1(int n) { OnMainThread(); var s = await A2(n); - OnPoolThread(); + OnMainThread(); await Task.Delay(100); - OnPoolThread(); + OnMainThread(); await A3(); - OnPoolThread(); + OnMainThread(); return s; }