Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

The code given here is a very simplified example and not for production usage.

The following snippet demonstrates TAP Task Synchronization using SemaphoreSlims in the context of upgrading an existing EAP application which relies on lock statements. This snippet of code doesn't do anything particularly useful, because it isn't supposed to - it is only to demonstrate one way of migrating from the EAP model to the TAP model.

See the blog entry for more information.

namespace Hotrian.com_Tutorials
{
public static class Program
{
public static async void Main()
{
var obj = new SensitiveResource();
// Store the values X = 10, Y = 20 in a single operation
// obj.SetResource(10, 20);
// Retrieve the resource values in a single operation
// var resource = obj.GetResource();
// Console.WriteLine($"X: {resource.Item1}, Y: {resource.Item2}"); // X: 10, Y: 20
// Store the values X = 10, Y = 20 in a single operation
await obj.SetResourceAsync(10, 20);
// Retrieve the resource values in a single operation
var resourceAsync = await obj.GetResourceAsync();
Console.WriteLine($"X: {resourceAsync.Item1}, Y: {resourceAsync.Item2}"); // X: 10, Y: 20
}
}
public class SensitiveResource
{
private readonly SemaphoreSlim _semaphoreSlim = new(1, 1);
private int _x;
private int _y;
// Remap the old EAP stubs to our new TAP methods, so older code can synchronize properly with newer code
/// <inheritdoc cref="GetResourceAsync"/>
public Tuple<int, int> GetResource() => GetResourceAsync().GetAwaiter().GetResult();
/// <inheritdoc cref="SetResourceAsync"/>
public void SetResource(int x, int y) => SetResourceAsync(x, y).GetAwaiter().GetResult();
/// <summary> Gets the Resources stored in a single operation. </summary>
public async Task<Tuple<int, int>> GetResourceAsync()
{
// Wait until the resource handle is available for us to block
await _semaphoreSlim.WaitAsync();
try
{
// Do sensitive operation
return new Tuple<int, int>(_x, _y);
}
finally
{
// Release the resource handle for the next thread
_semaphoreSlim.Release();
}
}
/// <summary> Sets the Resources to <paramref name="x"/> and <paramref name="y"/> in a single operation. </summary>
public async Task SetResourceAsync(int x, int y)
{
// Wait until the resource handle is available for us to block
await _semaphoreSlim.WaitAsync();
try
{
// Do sensitive operation
_x = x;
_y = y;
}
finally
{
// Release the resource handle for the next thread
_semaphoreSlim.Release();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment