并行运行两个异步任务并在 .NET 4.5 中收集结果 [英] Run two async tasks in parallel and collect results in .NET 4.5

查看:31
本文介绍了并行运行两个异步任务并在 .NET 4.5 中收集结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试获得一些我认为使用 .NET 4.5 很简单的东西

I've been trying for a while to get something I thought would be simple working with .NET 4.5

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

I want to fire off two long running tasks at same time and collect the
results in in the best C# 4.5 (RTM) way

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

The following works but I don't like it because:

  • 我希望 Sleep 成为一个异步方法,以便它可以await 其他方法
  • 它看起来很笨拙,Task.Run()
  • 我认为这根本没有使用任何新的语言功能!
  • I want Sleep to be an async method so it can await other methods
  • It just looks clumsy with Task.Run()
  • I don't think this is even using any new language features at all!

工作代码:

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) 在完成之前不会运行.即使 Sleepasync 并且我没有使用 await 或过早调用 .Result 也是如此.

This code doesn't work because the call to Sleep(5000) immediately starts the task running so Sleep(1000) doesn't run until it has completed. This is true even though Sleep is async and I'm not using await or calling .Result too soon.

我想也许有一种方法可以通过调用 async 方法来获得非运行的 Task,这样我就可以调用 Start() 在这两个任务上,但我不知道如何通过调用异步方法获得 Task.

I thought maybe there is a way to get a non-running Task<T> by calling an async method so I could then call Start() on the two tasks, but I can't figure out how to get a Task<T> from calling an async method.

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;
}

推荐答案

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

You should use Task.Delay instead of Sleep for async programming and then use Task.WhenAll to combine the task results. The tasks would run in parallel.

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;
        }
    }

这篇关于并行运行两个异步任务并在 .NET 4.5 中收集结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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