小编典典

并行运行两个异步任务,并在.NET 4.5中收集结果

c#

我已经尝试了一段时间,以获取一些我认为使用.NET 4.5会很简单的方法

我想同时启动两个长时间运行的任务,并
以最佳的C#4.5(RTM)方式收集结果

以下作品有效,但我不喜欢,因为:

  • 我想Sleep成为一个异步方法,以便可以使用await其他方法
  • 看起来笨拙 Task.Run()
  • 我认为这根本没有使用任何新的语言功能!

工作代码:

public static void Go()
{
    Console.WriteLine("Starting");

    var task1 = Task.Run(() => Sleep(5000));    
    var task2 = Task.Run(() => Sleep(3000));

    int totalSlept = task1.Result + task2.Result;

    Console.WriteLine("Slept for a total of " + totalSlept + " ms");
}

private static int Sleep(int ms)
{
    Console.WriteLine("Sleeping for " + ms);
    Thread.Sleep(ms);
    Console.WriteLine("Sleeping for " + ms + " FINISHED");
    return ms;
}

非工作代码:

更新:这实际上有效并且是正确的方法,唯一的问题是Thread.Sleep

该代码无法正常工作,因为对的调用会Sleep(5000)立即开始运行任务,因此Sleep(1000)直到完成后才运行。即使Sleep是这样async,我也没用await或打电话.Result太早,这是对的。

我以为也许有一种方法可以Task<T>通过调用async方法来使非运行状态,这样我就可以调用Start()这两个任务,但是我不知道如何Task<T>通过调用异步方法来获得a

public static void Go()
{
    Console.WriteLine("Starting");

    var task1 = Sleep(5000);    // blocks
    var task2 = Sleep(1000);

    int totalSlept = task1.Result + task2.Result;

    Console.WriteLine("Slept for " + totalSlept + " ms");
}

private static async Task<int> Sleep(int ms)
{
    Console.WriteLine("Sleeping for " + ms);
    Thread.Sleep(ms);
    return ms;
}

阅读 310

收藏
2020-05-19

共1个答案

小编典典

您应该使用Task.Delay而不是Sleep进行异步编程,然后使用Task.WhenAll组合任务结果。这些任务将并行运行。

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

            Console.WriteLine("Starting");

            var task1 = Sleep(5000);
            var task2 = Sleep(3000);

            int[] result = await Task.WhenAll(task1, task2);

            Console.WriteLine("Slept for a total of " + result.Sum() + " ms");

        }

        private async static Task<int> Sleep(int ms)
        {
            Console.WriteLine("Sleeping for {0} at {1}", ms, Environment.TickCount);
            await Task.Delay(ms);
            Console.WriteLine("Sleeping for {0} finished at {1}", ms, Environment.TickCount);
            return ms;
        }
    }
2020-05-19