ABP AsyncHelper.RunSync 内部实现

using System;
using System.Reflection;
using System.Threading.Tasks;
using Nito.AsyncEx;

namespace Abp.Threading
{
    
    
    /// <summary>
    /// Provides some helper methods to work with async methods.
    /// </summary>
    public static class AsyncHelper
    {
    
    
        /// <summary>
        /// Checks if given method is an async method.
        /// </summary>
        /// <param name="method">A method to check</param>
        public static bool IsAsync(this MethodInfo method)
        {
    
    
            return (
                method.ReturnType == typeof(Task) ||
                (method.ReturnType.GetTypeInfo().IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
            );
        }

        /// <summary>
        /// Checks if given method is an async method.
        /// </summary>
        /// <param name="method">A method to check</param>
        [Obsolete("Use MethodInfo.IsAsync() extension method!")]
        public static bool IsAsyncMethod(MethodInfo method)
        {
    
    
            return method.IsAsync();
        }

        /// <summary>
        /// Runs a async method synchronously.
        /// </summary>
        /// <param name="func">A function that returns a result</param>
        /// <typeparam name="TResult">Result type</typeparam>
        /// <returns>Result of the async operation</returns>
        public static TResult RunSync<TResult>(Func<Task<TResult>> func)
        {
    
    
            return AsyncContext.Run(func);
        }

        /// <summary>
        /// Runs a async method synchronously.
        /// </summary>
        /// <param name="action">An async action</param>
        public static void RunSync(Func<Task> action)
        {
    
    
            AsyncContext.Run(action);
        }
    }
}

这是 AsyncHelper 的全部代码,可以看到其实内部就是封装的 Nito.AsyncEx 其他什么都没做。

调用方式:AsyncHelper.RunSync(() => 方法名());


asynchelper在一个同步方法(非async)方法中等待async方法

    /// <summary>
    /// 异步调用助手类
    /// </summary>
    /// <see cref="http://www.tuicool.com/articles/QF73qaA"/>
    public static class AsyncHelper
    {
    
    
        public static void InvokeAndWait(Func<Task> asyncMethod)
        {
    
    
            // ReSharper disable once ConvertClosureToMethodGroup
            Task.Run(() => asyncMethod())
                .ContinueWith(t => t.Wait())
                .Wait();
        }

        public static T InvokeAndWait<T>(Func<Task<T>> asyncMethod)
        {
    
    
            var result = default(T);
            // ReSharper disable once ConvertClosureToMethodGroup
            Task.Run<T>(() => asyncMethod())
                .ContinueWith(t =>
                {
    
    
                    t.Wait();
                    result = t.Result;
                }).Wait();
            return result;
        }
    }
/// <summary>
/// 异步调用助手类
/// https://github.com/aspnet/AspNetIdentity.git
/// </summary>
public static class TaskAsyncHelper
{
    
    
    private static readonly TaskFactory _myTaskFactory = new TaskFactory(CancellationToken.None,
        TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);
    /// <summary>
    /// demo: return TaskAsyncHelper.RunSync(() => manager.UpdateAsync(role));
    /// </summary>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="func"></param>
    /// <returns></returns>
    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
    {
    
    
        var cultureUi = CultureInfo.CurrentUICulture;
        var culture = CultureInfo.CurrentCulture;
        return _myTaskFactory.StartNew(() =>
        {
    
    
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = cultureUi;
            return func();
        }).Unwrap().GetAwaiter().GetResult();
    }

    /// <summary>
    /// demo: TaskAsyncHelper.RunSync(() => manager.SendEmailAsync(userId, subject, body));
    /// </summary>
    /// <param name="func"></param>
    public static void RunSync(Func<Task> func)
    {
    
    
        var cultureUi = CultureInfo.CurrentUICulture;
        var culture = CultureInfo.CurrentCulture;
        _myTaskFactory.StartNew(() =>
        {
    
    
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = cultureUi;
            return func();
        }).Unwrap().GetAwaiter().GetResult();
    }
}

猜你喜欢

转载自blog.csdn.net/WuLex/article/details/121032009
ABP