简体   繁体   English

C#异步编程

[英]C# Asynchronous Programming

I have my Program.cs file: 我有我的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));

        }

    }
}

And here's the code for InterestingObject: 这是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);
        }
    }
}

I expect list = await interesting.GenerateListAsync(); 我希望list = await interesting.GenerateListAsync(); to run asynchronously while alsoList = interesting.GenerateList(); 异步运行,同时alsoList = interesting.GenerateList(); is running, effectively logging the output of GenerateList into my console while GenerateListAsync is doing the exact same, or to see GenerateListAsync finish near-instantly when GenerateList finishes. 正在运行,有效地将GenerateList的输出记录到我的控制台中,而GenerateListAsync完全相同,或者在GenerateListAsync完成时立即看到GenerateList结束。

However, looking into the console I see my application running GenerateListAsync and then run GenerateList afterwards. 但是,从控制台看,我看到我的应用程序正在运行GenerateListAsync ,然后再运行GenerateList

I'm doing this wrong but no source has been sufficient to solve this problem. 我做错了,但是没有任何资料足以解决这个问题。

I expect list = await interesting.GenerateListAsync(); 我希望list = await interesting.GenerateListAsync(); to run asynchronously while alsoList = interesting.GenerateList(); 异步运行,同时alsoList = interesting.GenerateList(); is running, 在跑,

That expectation is incorrect; 这种期望是不正确的; the entire point of await is that it does not continue past that point until the asynchronous operation is complete; 整个点await是,它不会继续过去的这一点,直到异步操作完成; it does this with a range of tricks including async state machines that allow an incomplete operation to be resumed when the results come back in. You can, however, just move the point at which you await , so that it doesn't cause this perceived blockage: 它通过一系列技巧来做到这一点,其中包括异步状态机,这些异步状态机允许在结果返回时恢复不完整的操作。但是,您可以移动 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

Note that async and parallelism are different things; 注意async和并行是不同的东西。 they can be used together, but that isn't what happens by default. 它们可以一起使用,但是默认情况下不会发生这种情况。 Note also: not all code is designed to allow concurrent usage, so you shouldn't do this kind of thing without knowing whether it is OK to use concurrent calls on a particular API. 另请注意:不是所有的代码被设计为允许并发使用,所以你不应该做这种事情不知道是否它是确定在一个特定的API使用并发呼叫。

Further to the answer, have a look at await (C# Reference) 进一步解答,看看await(C#参考)

The await operator is applied to a task in an asynchronous method to insert a suspension point in the execution of the method until the awaited task completes. await运算符应用于异步方法中的任务,以在该方法的执行中插入挂起点,直到完成等待的任务。 that's the reason in your application running GenerateListAsync and then run GenerateList afterwards. 这就是您的应用程序先运行GenerateListAsync,然后再运行GenerateList的原因。 To run the GenerateListAsync asynchronously you need to take the GenerateListAsync return in Task variable and then call GenerateList and after that use await for GenerateListAsync method. 要异步运行GenerateListAsync,您需要在Task变量中获取GenerateListAsync返回值,然后调用GenerateList,然后对GenerateListAsync方法使用await。

eg 例如

Task <List<int>> longRunningTask = interesting.GenerateListAsync();
        alsoList = interesting.GenerateList();
        list = await longRunningTask;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM