C# 如何在C中使用异步编程并行调用多个方法#

C# 如何在C中使用异步编程并行调用多个方法#,c#,asynchronous,parallel-processing,C#,Asynchronous,Parallel Processing,上面的代码返回到下面 public class Program { public static void Main(string[] args) { Start(); Console.ReadLine(); } private static async Task Start() { var m1 = method1(); var m2 = method2(); await

上面的代码返回到下面

public class Program
{
    public static void Main(string[] args)
    {
        Start();
        Console.ReadLine();
    }

    private static async Task Start()
    {
        var m1 = method1();
        var m2 = method2();

        await Task.WhenAll(m1, m2);
    }


    private static async Task method1()
    {
        Console.WriteLine("Method1 - Start");
        Thread.Sleep(1000);
        Console.WriteLine("Method1 - End");
    }
    private static async Task method2()
    {
        Console.WriteLine("Method2 - Start");
        Thread.Sleep(1000);
        Console.WriteLine("Method2 - End");
    }
}
我想要像这样的输出

Method1 - Start
Method1 - End
Method2 - Start
Method2 - End
如何实现基本上如何并行运行异步方法
公共类程序
{
公共静态异步任务Main()
{
等待开始();
Console.ReadLine();
}
专用静态异步任务启动()
{
var m1=method1();
var m2=method2();
等待任务。WhenAll(m1,m2);
}
专用静态异步任务方法1()
{
Console.WriteLine(“方法1-启动”);
等待任务。延迟(1000);
Console.WriteLine(“方法1-结束”);
}
专用静态异步任务方法2()
{
Console.WriteLine(“方法2-启动”);
等待任务。延迟(1000);
Console.WriteLine(“方法2-结束”);
}
}
选项B-带
任务。运行

公共类程序
{
公共静态异步任务Main()
{
等待开始();
Console.ReadLine();
}
专用静态异步任务启动()
{
var m1=Task.Run(()=>method1());
var m2=Task.Run(()=>method2());
等待任务。WhenAll(m1,m2);
}
私有静态void方法1()
{
Console.WriteLine(“方法1-启动”);
睡眠(1000);
Console.WriteLine(“方法1-结束”);
}
私有静态void方法2()
{
Console.WriteLine(“方法2-启动”);
睡眠(1000);
Console.WriteLine(“方法2-结束”);
}
}

或者您可以使用
Task.Yield()

这一个比使用
Task.Delay()
稍微“并行”,因为它会立即返回一个未完成的任务,但随着延迟,“异步性”只有在到达代码行时才会发生。如果在延迟之前有长时间运行的同步代码,则会延迟后续方法(在本例中为method2)的执行

编辑


有关

替换
线程的更详细说明。将睡眠
替换为
等待任务。延迟
。如果希望“真正”并行,请使用任务调用方法。运行或在新线程上运行。异步本身并不是关于并行性的,并行度在很大程度上取决于实际方法的结构。试想一下,如果method1()在等待任务之前执行长时间运行的代码。延迟,它将是同步的,method2()在代码完成并到达第一个等待任务之前不会启动。
Task.Yield
不是切换到
ThreadPool
的可靠(与平台无关)方法。它只有在没有环境
同步上下文的情况下才会这样做,而且只是偶然,因为它是专门为安装了同步上下文的环境而设计的。出于这个原因,我认为这个解决方案是一个黑客,我建议使用“<代码>任务”。运行< /代码>方法,它是一种非上下文感知机制,专门用于将工作卸载到<代码>线程池< /代码>。使用<代码>任务。Delay < /代码>(事实上,任何等待的可等待的)。与
SynchronizationContext
具有相同的缺点(但至少可以使用
ConfigureAwait(false)
)。自dotnet核心以来,无论控制台应用程序还是AspNet都没有代码>同步化上下文< /代码>附件,我都不认为它是黑客攻击,但我必须同意,谨慎建议。YAAP,<代码>等待任务。Delay(1)< /C>可能是黑客攻击的更坏版本。如果有人真的想避免<代码>任务。出于某种原因运行,他们可以考虑使用像NoSeriTo的自定义等待器,这是专门用来执行切换到<代码>线程池< /代码>的。
Method1 - Start
Method2 - Start
Method1 - End
Method2 - End
public class Program
{
    public static void Main(string[] args)
    {
        Start();
        Console.ReadLine();
    }

    private static async Task Start()
    {
        var m1 = method1();
        var m2 = method2();

        await Task.WhenAll(m1, m2);
    }


    private static async Task method1()
    {
        await Task.Yield();
        Console.WriteLine("Method1 - Start");
        Thread.Sleep(1000);
        Console.WriteLine("Method1 - End");
    }
    private static async Task method2()
    {
        await Task.Yield();
        Console.WriteLine("Method2 - Start");
        Thread.Sleep(1000);
        Console.WriteLine("Method2 - End");
    }
}