异步方法未并行运行 [英] Async method not running in parallel

查看:81
本文介绍了异步方法未并行运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码的B方法中,代码Trace.TraceInformation("B-Started");永远不会被打电话.

In the following code, in the B method, the code Trace.TraceInformation("B - Started"); never gets called.

该方法应该并行运行吗?

Should the method be running in parallel?

using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        private static async Task A()
        {
            for (;;)
            {
            }
        }


        private static async Task B()
        {
            Trace.TraceInformation("B - Started");
        }

        static void Main(string[] args)
        {
            var tasks = new List<Task> { A(), B() };
            Task.WaitAll(tasks.ToArray());
        }
    }
}

推荐答案

简短答案

否,当您编写了两个async方法时,它们确实不是并行运行的.将await Task.Yield();添加到您的第一个方法中(例如,在循环内)允许他们这样做,但是有更多更合理,更直接的方法,这很大程度上取决于您的实际需要(在单个步骤上交错执行)线程?实际上是在多个线程上并行执行?).

No, as you wrote your two async methods, they are indeed not running in parallel. Adding await Task.Yield(); to your first method (e.g. inside the loop) would allow them to do so, but there are more reasonable and straightforward methods, highly depending on what you actually need (interleaved execution on a single thread? Actual parallel execution on multiple threads?).

好答案

首先,将函数声明为async并不会使它们固有地异步运行.它相当简化了语法,在这里可以了解更多有关概念的信息:异步编程使用Async和Await

First of all, declaring functions as async does not inherently make them run asynchronously or something. It rather simplifies the syntax to do so - read more about the concepts here: Asynchronous Programming with Async and Await

实际上,A根本不是异步的,因为其方法体内没有单个await.直到首次使用await的指令都像常规方法一样同步运行.

Effectively A is not asynchronous at all, as there is not a single await inside its method body. Instructions up to the first use of await run synchronously like a regular method would.

此后,您await的对象确定接下来将发生什么,即其余方法在其中运行的上下文.

From then on, the object that you await determines what happens next, i.e. the context that the remaining method runs in.

强制在另一个线程上执行任务,请使用Task.Run或类似的命令.

To force execution of a task to happen on another thread, use Task.Run or similar.

在这种情况下,添加await Task.Yield()可以解决问题,因为当前的同步上下文是null,而这恰好确实导致任务调度程序(应该为ThreadPoolTaskScheduler)在线程池线程上执行其余指令-某些环境或配置可能会导致您只有其中之一,因此仍然无法并行运行.

In this scenario, adding await Task.Yield() does the trick since the current synchronization context is null and this happens to indeed cause the task scheduler (should be ThreadPoolTaskScheduler) to execute the remaining instuctions on a thread-pool thread - some environment or configuration might cause you to only have one of them, so things would still not run in parallel.

摘要

故事的寓意是:注意两个概念之间的差异:

The moral of the story is: Be aware of the differences between two concepts:

  • 并发(通过合理使用async/await启用)和
  • 并行性(仅当并发任务按正确的方式排定 时发生,或者如果您使用Task.RunThread等强制实施并行化,则这种情况会发生.反正async的使用是完全无关的
  • concurrency (which is enabled by using async/await reasonably) and
  • parallelism (which only happens when concurrent tasks get scheduled the right way or if you enforce it using Task.Run, Thread, etc. in which case the use of async is completely irrelevant anyway)

这篇关于异步方法未并行运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆