异步等待同步运行 [英] Async Await Running Synchronously

查看:72
本文介绍了异步等待同步运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习异步/等待并创建了以下测试代码,但是它正在同步运行,我不确定为什么.

I'm trying to learn async/await and created the following test code, however it is running synchronously and I'm not sure why.

    class Program
    {                
        static void Main()
        {
            TestAsync testAsync = new TestAsync();
            testAsync.Run();

            Console.Read();
        }        
    }

    public class TestAsync
    {
        public async void Run()
        {
            Task<int> resultTask = GetInt();
            Console.WriteLine("2)");
            int x = await resultTask;
            Console.WriteLine("4)");
        }
        public async Task<int> GetInt()
        {
            Task<int> GetIntAfterLongWaitTask = GetIntAfterLongWait();
            Console.WriteLine("1)");
            int x = await GetIntAfterLongWaitTask;//Expecting execution to go back to Run() since it's not done yet.
            Console.WriteLine("3)");
            return x;
        }

        public async Task<int> GetIntAfterLongWait()
        {
            for (int i = 0; i < 500000000; i++)
            {
                if (i % 10000000 == 0)
                {
                    Console.WriteLine(i);
                }                
            }

            return 23;
        }
    }

输出为:

<long list of ints>
1)
3)
2)
4)

我希望是

<long list of ints>
1)
2)
3)
4)

1)位于一长串整数中.

为什么要同步运行?

推荐答案

令人困惑的是, async 关键字不会使您的方法神奇地异步化.相反,您可以考虑将 async 方法作为状态机的设置(请参阅详细说明

Confusingly enough, the async keyword will not turn your methods magically asynchronous. Instead, you can consider async methods as a setup for a state machine (see a detailed explanation here), where you schedule the chain of operations by the await calls.

因此,您的异步方法必须尽快执行.在这种设置方法中请勿执行任何阻止操作.您的 GetIntAfterLongWait 方法是一项阻止操作,由于它不包含任何 await ,因此调用此方法后,整个内容将立即执行(不包含任何 await 该方法中没有要设置异步延续的内容.对此也必须有警告.

For that reason, your async methods must execute as fast as possible. Do not do any blocking operation in such a setup method. Your GetIntAfterLongWait method is a blocking operation and since it does not contain any awaits the whole content will be executed immediately when the method is called (without any await there is nothing in the method to setup for an async continuation). There must be also a warning about that.

如果要在async方法中执行阻塞操作,则可能的选择是通过 await Task.Run(()=> MyLongOperation()); 致电.

If you have a blocking operation, which you want to execute in the async method, a possible option is to schedule it by an await Task.Run(() => MyLongOperation()); call.

因此,例如,下面的示例将立即返回,因为在第一个 await 之前没有任何要执行的操作.内部等待的任务完成后,return语句将作为继续执行异步执行:

So for example the following example will return immediately because there is nothing to execute before the first await. The return statement will be executed asynchronously as a continuation after the inner awaited task finished:

public async Task<int> GetIntAfterLongWait()
{
    await Task.Run(() =>
    {
        for (int i = 0; i < 500000000; i++)
        {
            if (i % 10000000 == 0)
            {
                Console.WriteLine(i);
            }                
        }
    });

    return 23;
}

有关更多详细信息,请参见上面的链接.

For more details see the link above.

更新:

此版本将打印:

1)
2)
<long list of ints> - but 0 can be before even 1) as Task.Run uses another thread
3)
4)

这篇关于异步等待同步运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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