从同步方法中调用异步方法

哈里森

我正在尝试从同步方法运行异步方法。但我不能等待异步,因为我在一个同步方法方法。我一定不能理解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但出现错误

“ await”运算符只能在异步方法中使用。考虑使用“异步”修饰符标记此方法,并将其返回类型更改为“任务”

但是,如果我使用async修饰符,这将是一个异步操作。因此,如果我的呼叫GetData1不使用await运算符,将无法控制在第一次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;
    }
S队

Task<TResult>.Result(或Task.Wait()无结果时)类似于await,但是同步操作。您应该更改GetData1()为使用它。这是要更改的部分:

Task<Data> dataTask = Task.WhenAny(runningTasks).Result;
runningTasks.Remove(dataTask);
myData = gameTask.Result;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

异步方法调用同步方法

来自分类Dev

同步调用异步方法

来自分类Dev

异步调用同步方法

来自分类Dev

在Xamarin Forms中的PCL中以同步方法调用异步函数

来自分类Dev

如何从石英计划作业中同步调用异步方法

来自分类Dev

如何从 C# 中的同步调用异步方法?

来自分类Dev

如何同步调用异步(等待)方法?

来自分类Dev

带有同步方法调用的异步任务

来自分类Dev

同步调用异步方法时出错

来自分类Dev

如何同步调用异步(等待)方法?

来自分类Dev

从同步Task调用方法的异步或同步版本更好吗?

来自分类Dev

在非异步方法中调用异步方法

来自分类Dev

调用异步方法时,StreamWriter使用同步调用

来自分类Dev

调用异步方法的同步方法上的nunit async / await断言

来自分类Dev

PHP中的异步方法调用

来自分类Dev

PHP中的异步方法调用

来自分类Dev

在单元测试中同步调用异步方法是否不正确?

来自分类Dev

如何在Windows Phone 8中同步调用异步方法

来自分类Dev

如何在Windows Phone 8中同步调用异步方法

来自分类Dev

具有同步和异步调用者的同步方法中的Thread.Sleep或Task.Delay

来自分类Dev

在一种方法中调用同步和异步方法(api / UI)的正确方法是什么

来自分类Dev

从异步调用void同步方法-无法等待void

来自分类Dev

在EJB Singleton上调用异步和同步方法

来自分类Dev

如何使用同步方法正确调用异步服务

来自分类Dev

在WebApi方法中调用异步方法

来自分类Dev

异步调用同步方法比自然异步方法更快地完成任务

来自分类Dev

如何在异步方法调用中传递异步方法委托?

来自分类Dev

异步运行同步方法

来自分类Dev

运行同步方法异步

Related 相关文章

热门标签

归档