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.

Revisions

  1. zHaytam created this gist Sep 22, 2021.
    49 changes: 49 additions & 0 deletions BlogPost7_TcsUtil.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    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);
    }
    }
    }