Skip to content
Task-like structs which capture no synchronization context on the await operations.
Branch: master
Clone or download
ufcpp Merge pull request #17 from WillSullivan/master
Removed unused and nonexistent references
Latest commit 1fa559a Apr 10, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/ContextFreeTasks SDK-based csproj Jan 7, 2018
tests/UnitTestNet45 Removed unused and nonexistent references Apr 10, 2018
.gitignore Initial commit Nov 19, 2016
ContextFreeTask.sln SDK-based csproj Jan 7, 2018
LICENSE Initial commit Nov 19, 2016
readme.md Update readme.md Jan 6, 2018

readme.md

ContextFreeTask

Usage

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.

private async ContextFreeTask FAsync() { ... }
private async ContextFreeTask<T> FAsync<T>() { ... }

These ignore the current synchronization context in the methods. You do not have to write ConfigureAwait(false) anymore.

Task-like

In C# 7, async methods may return other types in addition to Task, Task<T> and void. The returned type must satisfy a certain pattern. These types are called "Task-like".

The ContextFreeTask struct in this library satisfies the "Task-like" pattern and the "awaitable" pattern.

What ContextFreeTask does

The methods which return ContextFreeTask do not capture the synchronization context.

For example, you can use this as following:

// All awaits in this method don't capture SynchronizationContext
private async ContextFreeTask FAsync()
{
    // Whatever current context is
    await Task.Delay(100);
    // no context here
    await Task.Delay(100);
    // no context here
}

This code behaves almost the same as the following:

private async Task FAsync()
{
    await Task.Delay(100).ConfigureAwait(false);
    await Task.Delay(100).ConfigureAwait(false);
}

Implementation

The ContextFreeTask struct is a thin wrapper of Task class.

public struct ContextFreeTask
{
    public Task Task { get; }
}

And the ContextFreeTask<T> is that of Task<T>.

public struct ContextFreeTask<T>
{
    public Task<T> Task { get; }
}

Those AsyncMethodBuilders always clear current synchronization context.

public struct AsyncContextFreeTaskMethodBuilder
{
    private AsyncTaskMethodBuilder _methodBuilder;

    public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
        where TAwaiter : INotifyCompletion
        where TStateMachine : IAsyncStateMachine
    {
        var prevContext = SynchronizationContext.Current;
        try
        {
            SynchronizationContext.SetSynchronizationContext(null);
            _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
        }
        finally
        {
            SynchronizationContext.SetSynchronizationContext(prevContext);
        }
    }
}
You can’t perform that action at this time.