How to call asynchronous method from synchronous method in C#?

后端 未结 15 1030
星月不相逢
星月不相逢 2020-11-21 06:27

I have a public async void Foo() method that I want to call from synchronous method. So far all I have seen from MSDN documentation is calling async methods via

15条回答
  •  清酒与你
    2020-11-21 06:49

    Microsoft built an AsyncHelper (internal) class to run Async as Sync. The source looks like:

    internal static class AsyncHelper
    {
        private static readonly TaskFactory _myTaskFactory = new 
          TaskFactory(CancellationToken.None, 
                      TaskCreationOptions.None, 
                      TaskContinuationOptions.None, 
                      TaskScheduler.Default);
    
        public static TResult RunSync(Func> func)
        {
            return AsyncHelper._myTaskFactory
              .StartNew>(func)
              .Unwrap()
              .GetAwaiter()
              .GetResult();
        }
    
        public static void RunSync(Func func)
        {
            AsyncHelper._myTaskFactory
              .StartNew(func)
              .Unwrap()
              .GetAwaiter()
              .GetResult();
        }
    }
    

    The Microsoft.AspNet.Identity base classes only have Async methods and in order to call them as Sync there are classes with extension methods that look like (example usage):

    public static TUser FindById(this UserManager manager, TKey userId) where TUser : class, IUser where TKey : IEquatable
    {
        if (manager == null)
        {
            throw new ArgumentNullException("manager");
        }
        return AsyncHelper.RunSync(() => manager.FindByIdAsync(userId));
    }
    
    public static bool IsInRole(this UserManager manager, TKey userId, string role) where TUser : class, IUser where TKey : IEquatable
    {
        if (manager == null)
        {
            throw new ArgumentNullException("manager");
        }
        return AsyncHelper.RunSync(() => manager.IsInRoleAsync(userId, role));
    }
    

    For those concerned about the licensing terms of code, here is a link to very similar code (just adds support for culture on the thread) that has comments to indicate that it is MIT Licensed by Microsoft. https://github.com/aspnet/AspNetIdentity/blob/master/src/Microsoft.AspNet.Identity.Core/AsyncHelper.cs

提交回复
热议问题