首页 > 解决方案 > C# 异步编程

问题描述

我有我的 Program.cs 文件:

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

namespace AsyncTest
{
    class Program
    {

        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            var interesting = new InterestingObject();

            List<int> list;
            List<int> alsoList;

            list = await interesting.GenerateListAsync();
            alsoList = interesting.GenerateList();

            Console.WriteLine("Done! :)");

            list    .ForEach(xs => Console.WriteLine(xs));
            alsoList.ForEach(xs => Console.WriteLine (xs));

        }

    }
}

这是 InterestingObject 的代码:

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

namespace AsyncTest
{
    public class InterestingObject
    {
        public InterestingObject()
        {
        }

        public List<int> GenerateList()
        {

            Console.WriteLine("Gonna generate the list!");

            var list = new List<int>();
            int i = 0;
            while (i < 5)
            {

                Random random = new Random();
                list.Add(random.Next());
                Console.WriteLine("Generated a new int!");
                VeryHeavyCalculations();

                i++;
            }

            return list;

        }

        public async Task<List<int>> GenerateListAsync()
        {

            Console.WriteLine("Gonna generate the list async!");

            var list = new List<int>();
            int i = 0;
            while (i < 5)
            {

                Random random = new Random();
                list.Add(random.Next ());
                Console.WriteLine("Generated a new int asyncronously!");
                await Task.Run(() => VeryHeavyCalculations());

                i++;
            }

            return list;

        }

        public void VeryHeavyCalculations()
        {
            Thread.Sleep (1000);
        }
    }
}

我希望list = await interesting.GenerateListAsync();在运行时异步运行,在执行完全相同的操作时alsoList = interesting.GenerateList();有效地将输出记录GenerateList到我的控制台中,或者在完成时几乎立即完成。GenerateListAsyncGenerateListAsyncGenerateList

但是,查看控制台我看到我的应用程序正在运行GenerateListAsync,然后运行GenerateList

我做错了,但没有足够的资源来解决这个问题。

标签: c#

解决方案


我希望list = await interesting.GenerateListAsync();在运行时异步alsoList = interesting.GenerateList();运行,

这种期望是不正确的;的全部意义在于,在异步操作完成之前await,它不会继续超过该点;它通过一系列技巧来做到这一点,包括异步状态机,允许在结果返回时恢复不完整的操作。但是,您可以移动您的点await,这样它就不会导致这种感知阻塞:

List<int> list;
List<int> alsoList;

var pending = interesting.GenerateListAsync(); // no await
alsoList = interesting.GenerateList();
list = await pending; // essentially "joins" at this point... kind of

请注意,async并行性是不同的东西;它们可以一起使用,但这不是默认情况下发生的。另请注意:并非所有代码都设计为允许并发使用,因此您不应该在不知道是否可以在特定 API 上使用并发调用的情况下做这种事情


推荐阅读