C# async Task - C#で同期式メソッドから非同期式メソッドを呼び出すには?

C# async void / c# / async-await

私が持っている public async void Foo() 私は同期メソッドから呼び出したいというメソッドを。これまでのところ、MSDN ドキュメントから見たのは、非同期メソッドを介して非同期メソッドを呼び出すことだけですが、私のプログラム全体は非同期メソッドで構築されていません。

BoltClock



Answer #1

MicrosoftはAsyncをSyncとして実行するためのAsyncHelper(内部)クラスを作りました。ソースは以下のようになっています。

internal static class AsyncHelper
{
    private static readonly TaskFactory _myTaskFactory = new 
      TaskFactory(CancellationToken.None, 
                  TaskCreationOptions.None, 
                  TaskContinuationOptions.None, 
                  TaskScheduler.Default);

    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
    {
        return AsyncHelper._myTaskFactory
          .StartNew<Task<TResult>>(func)
          .Unwrap<TResult>()
          .GetAwaiter()
          .GetResult();
    }

    public static void RunSync(Func<Task> func)
    {
        AsyncHelper._myTaskFactory
          .StartNew<Task>(func)
          .Unwrap()
          .GetAwaiter()
          .GetResult();
    }
}

Microsoft.AspNet.Identity ベースクラスには Async メソッドしかありませんが、これを Sync として呼び出すために、次のような拡張メソッドを持つクラスがあります(使用例)。

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

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