Skip to content

Instantly share code, notes, and snippets.

@zHaytam
Created September 22, 2021 20:43
Show Gist options
  • Save zHaytam/35ea970cd31613a34a6cf24e392afbc7 to your computer and use it in GitHub Desktop.
Save zHaytam/35ea970cd31613a34a6cf24e392afbc7 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Blazor.Diagrams.Interop
{
public static class TcsUtil
{
private static readonly Type _tcsType = typeof(TaskCompletionSource<>);
private static readonly ConcurrentDictionary<Type, Action<object, object>> _setResults = new ConcurrentDictionary<Type, Action<object, object>>();
private static readonly ConcurrentDictionary<Type, Action<object, Exception>> _setExceptions = new ConcurrentDictionary<Type, Action<object, Exception>>();
public static void SetResult(object tcs, Type resultType, object result)
{
var tcsSpecificType = _tcsType.MakeGenericType(resultType);
var setResult = _setResults.GetOrAdd(tcsSpecificType, (tcsSpecificType) =>
{
var tcsParamExpr = Expression.Parameter(typeof(object), "tcs");
var resultParamExpr = Expression.Parameter(typeof(object), "result");
var tcsConvertExpr = Expression.Convert(tcsParamExpr, tcsSpecificType);
var resultConvertExpr = Expression.Convert(resultParamExpr, resultType);
var setResultExpr = Expression.Call(tcsConvertExpr, "TrySetResult", Type.EmptyTypes, resultConvertExpr);
return Expression.Lambda<Action<object, object>>(setResultExpr, tcsParamExpr, resultParamExpr).Compile();
});
setResult(tcs, result);
}
public static void SetException(object tcs, Type resultType, Exception exception)
{
var tcsSpecificType = _tcsType.MakeGenericType(resultType);
var setException = _setExceptions.GetOrAdd(tcsSpecificType, (tcsSpecificType) =>
{
var tcsParamExpr = Expression.Parameter(typeof(object), "tcs");
var exParamExpr = Expression.Parameter(typeof(Exception), "ex");
var tcsConvertExpr = Expression.Convert(tcsParamExpr, tcsSpecificType);
var setResultExpr = Expression.Call(tcsConvertExpr, "TrySetException", Type.EmptyTypes, exParamExpr);
return Expression.Lambda<Action<object, Exception>>(setResultExpr, tcsParamExpr, exParamExpr).Compile();
});
setException(tcs, exception);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment