Llamando a un método asíncrono desde un método síncrono

Estoy intentando ejecutar métodos asíncronos desde un método síncrono. Pero no puedoesperar laasíncrono Método ya que estoy en un método síncrono. No debo entender el TPL ya que es la primera vez que lo uso.

private void GetAllData()
{
    GetData1()
    GetData2()
    GetData3()
}

Cada método necesita el método anterior para finalizar, ya que los datos del primero se utilizan para el segundo.

Sin embargo, dentro de cada método quiero iniciar múltiplesTask Operaciones para agilizar el rendimiento. Entonces quiero esperar a que todos terminen.

GetData1 se ve así

    internal static void GetData1 ()
    {
        const int CONCURRENCY_LEVEL = 15; 
        List<Task<Data>> dataTasks = new List<Task<Data>>();
        for (int item = 0; item < TotalItems; item++)
        {
            dataTasks.Add(MyAyncMethod(State[item]));
        }
        int taskIndex = 0;
        //Schedule tasks to concurency level (or all)
        List<Task<Data>> runningTasks = new List<Task<Data>>();
        while (taskIndex < CONCURRENCY_LEVEL && taskIndex < dataTasks.Count)
        {
            runningTasks.Add(dataTasks[taskIndex]);
            taskIndex++;
        }

        //Start tasks and wait for them to finish
        while (runningTasks.Count > 0)
        {
            Task<Data> dataTask = await Task.WhenAny(runningTasks);
            runningTasks.Remove(dataTask);
            myData = await dataTask;


            //Schedule next concurrent task
            if (taskIndex < dataTasks.Count)
            {
                runningTasks.Add(dataTasks[taskIndex]);
                taskIndex++;
            }
        }
        Task.WaitAll(dataTasks.ToArray()); //This probably isn't necessary
    }

Estoy usando aguardar aquí pero me sale un error

El operador 'await' solo se puede utilizar dentro de un método asíncrono. Considere marcar este método con el modificador 'asíncrono' y cambiar su tipo de retorno a 'Tarea'

Sin embargo, si uso el modificador asíncrono, esta será una operación asíncrona. Por lo tanto, si mi llamada aGetData1 no utiliza el operador await no controlará, vaya a GetData2 en la primera espera, ¿qué es lo que estoy tratando de evitar? ¿Es posible mantener GetData1 como un método síncrono que llama a un método asíncrono? ¿Estoy diseñando incorrectamente el método asíncrono? Como puedes ver estoy bastante confundido.

Esto podría ser un duplicado de¿Cómo llamar al método asíncrono del método síncrono en C #? Sin embargo, no estoy seguro de cómo aplicar las soluciones proporcionadas allí ya que estoy iniciando varias tareas, quieroWaitAny, realice un poco más de procesamiento para esa tarea, luego espere a que todas las tareas terminen antes de devolver el control a la persona que llama.

ACTUALIZAR

Aquí está la solución con la que fui basada en las respuestas a continuación:

    private static List<T> RetrievePageTaskScheduler<T>(
        List<T> items,
        List<WebPageState> state,
        Func<WebPageState, Task<List<T>>> func)
    {
        int taskIndex = 0;

        // Schedule tasks to concurency level (or all)
        List<Task<List<T>>> runningTasks = new List<Task<List<T>>>();
        while (taskIndex < CONCURRENCY_LEVEL_PER_PROCESSOR * Environment.ProcessorCount
            && taskIndex < state.Count)
        {
            runningTasks.Add(func(state[taskIndex]));
            taskIndex++;
        }

        // Start tasks and wait for them to finish
        while (runningTasks.Count > 0)
        {
            Task<List<T>> task = Task.WhenAny(runningTasks).Result;
            runningTasks.Remove(task);

            try
            {
                items.AddRange(task.Result);
            }
            catch (AggregateException ex)
            {
                /* Throwing this exception means that if one task fails 
                 * don't process any more of them */

                // https://stackoverflow.com/questions/8853693/pattern-for-implementing-sync-methods-in-terms-of-non-parallel-task-translating
                System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(
                    ex.Flatten().InnerExceptions.First()).Throw();
            }

            // Schedule next concurrent task
            if (taskIndex < state.Count)
            {
                runningTasks.Add(func(state[taskIndex]));
                taskIndex++;
            }
        }

        return items;
    }

Respuestas a la pregunta(3)

Su respuesta a la pregunta