Вызов асинхронного метода из синхронного метода
Я пытаюсь запустить асинхронные методы из синхронного метода. Но я не могуЖдите асинхронной метод, так как я в синхронном методе. Я не должен понимать TPL, поскольку это первый раз, когда я его использую.
private void GetAllData()
{
GetData1()
GetData2()
GetData3()
}
Каждому методу требуется предыдущий метод для завершения, поскольку данные из первого используются для второго.
Тем не менее, внутри каждого метода я хочу начать несколькоTask
операции, чтобы ускорить производительность. Тогда я хочу подождать, пока все они закончат.
GetData1 выглядит так
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
}
Я использую жду здесь, но получаю ошибку
Оператор 'await' может использоваться только внутри асинхронного метода. Попробуйте пометить этот метод модификатором async и изменить его тип возвращаемого значения на Task
Однако, если я использую модификатор async, это будет асинхронная операция. Поэтому, если мой звонокGetData1
не использует оператор await и не контролирует переход в GetData2 с первого ожидания, чего я пытаюсь избежать? Можно ли сохранить GetData1 как синхронный метод, который вызывает асинхронный метод? Я неправильно проектирую асинхронный метод? Как вы можете видеть, я в замешательстве.
Это может быть дубликатомКак вызвать асинхронный метод из синхронного метода в C #? Тем не менее, я не уверен, как применять представленные там решения, так как я запускаю несколько задач, хочуWaitAny
Выполните немного больше обработки для этой задачи, затем дождитесь завершения всех задач, прежде чем передать управление вызывающей стороне.
ОБНОВИТЬ
Вот решение, которое я выбрал, основываясь на ответах ниже:
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;
}