.Net Framework 4.6.1以降のC#にて、戻り値がvoidで引数にActionを使う非同期処理用のメソッドに対してasync/awaitを適用する方法はあるのでしょうか?

下記のサンプルコードにおけるReadSQLWrapperメソッドのように、Actionで戻ってきた値をラムダ式の外側で取得して、非同期実行の戻り値として返せることが理想です。

サンプルコード修正の前提条件としてDBManagerMock自体は改修できないものとさせてください。

using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program().Execute();
        }

        private void Execute()
        {
            var sqls = new string[] { "select hoge;", "select fuga;", "select piyo;" };
            //理想のコード
            var tasks = sqls.Select(ReadSQLWrapper).ToArray();
            Task.WaitAll(tasks);    //Taskなら同期実行も非同期実行も思うがまま
            tasks.Select(t => t.Result).ToList().ForEach(Console.WriteLine);
        }

        //懸案となる、うまく動作しないasyncの疑似メソッド
        private async Task<string> ReadSQLWrapper(string sql)
        {
            var db = new DBManagerMock();
            string result = "ダミーの初期化子"; //DBManagerMockのReadSQLメソッドのActionを返したい
            //await db.ReadSQL(sql, r => { result = r; }); //エラー CS4008  'void' を待機することができません
            return result;
        }
    }

    //このクラスは改修不可
    public class DBManagerMock
    {
        public void ReadSQL(string sql, Action<string> result)
        {
            //非同期でDB接続して結果を返す
            result(string.Format("{0}の実行結果", sql));
        }
    }
}

AutoResetEventでも理想に近いコーディングは可能ですが、非同期実行時の実行待ち件数の上限があるため、async Taskを返す方がより利便性が高いと期待しています。

そもそもasync/awaitの理解に問題があるようでしたらご指摘いただければ幸いです。