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;


        }



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


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


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


POPMUISE
浏览 75回答 2
2回答

米琪卡哇伊

我希望list = await interesting.GenerateListAsync();在运行时异步alsoList = interesting.GenerateList();运行,这种期望是不正确的;的全部要点是在异步操作完成之前await,它不会继续超过该点;它通过一系列技巧来做到这一点,包括异步状态机,允许在结果返回时恢复未完成的操作。但是,您可以只移动您所在的点await,这样就不会导致这种感知阻塞:List<int> list;List<int> alsoList;var pending = interesting.GenerateListAsync(); // no awaitalsoList = interesting.GenerateList();list = await pending; // essentially "joins" at this point... kind of请注意,async并行性是不同的东西;它们可以一起使用,但默认情况下不会发生这种情况。另请注意:并非所有代码都设计为允许并发使用,因此您不应该在不知道是否可以在特定 API 上使用并发调用的情况下做这种事情。

宝慕林4294392

关于答案,请查看await(C# 参考)await运算符应用于异步方法中的任务,以在该方法的执行中插入一个挂起点,直到等待的任务完成。这就是您的应用程序运行 GenerateListAsync 然后再运行 GenerateList 的原因。要异步运行 GenerateListAsync,您需要在 Task 变量中获取 GenerateListAsync 返回值,然后调用 GenerateList,然后使用等待 GenerateListAsync 方法。例如Task&nbsp;<List<int>>&nbsp;longRunningTask&nbsp;=&nbsp;interesting.GenerateListAsync(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alsoList&nbsp;=&nbsp;interesting.GenerateList(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;=&nbsp;await&nbsp;longRunningTask;
打开App,查看更多内容
随时随地看视频慕课网APP