private static async Task <TResult> PerformTaskAsync <TArg, TResult>(
            Func <TArg, TResult> func, TArg arg,
            TaskScheduler scheduler, CancellationToken cancellationToken) where TArg : struct
        {
            // Get a pooled delegate that can be used to prevent having to alloc a new lambda that calls 'func' while
            // capturing 'arg'.  This is needed as Task.Factory.StartNew has no way to pass extra data around with it
            // except by boxing it as an object.
            using var _ = PooledDelegates.GetPooledFunction(func, arg, out var boundFunction);

            var task = Task.Factory.StartNew(boundFunction, cancellationToken, TaskCreationOptions.None, scheduler);

            return(await task.ConfigureAwait(false));
        }
Пример #2
0
        public static TValue GetOrAdd <TKey, TArg, TValue>(this ConcurrentDictionary <TKey, TValue> dictionary, TKey key, Func <TKey, TArg, TValue> valueFactory, TArg factoryArgument)
            where TKey : notnull
        {
#if NETCOREAPP
            return(dictionary.GetOrAdd(key, valueFactory, factoryArgument));
#else
            if (dictionary.TryGetValue(key, out var value))
            {
                return(value);
            }

            using var _ = PooledDelegates.GetPooledFunction(valueFactory, factoryArgument, out var boundFunction);
            return(dictionary.GetOrAdd(key, boundFunction));
#endif
        }