意外的异步/等待行为

时间:2016-04-07 16:54:10

标签: c# asynchronous async-await

这是一个模仿我的实际案例流程的程序:

using System;
using System.Threading.Tasks;

namespace TestAsync
{
    interface IInterface
    {
        Task<int> DoSomething(int i);
    }

    class MyClass : IInterface
    {
        public async void MainAsync()
        {
            var i = 1;
            Console.WriteLine("Start MainAsync:" + i);
            var t = DoSomething(i);
            Console.WriteLine("After DoSomething: " + i );
            i = await t;
            Console.WriteLine("Done waiting: " + i);
        }

        public async Task<int> DoSomething(int i)
        {
            i = i + 1;
            Console.WriteLine("In Something:" + i);
            await Task.Delay(1000);
            Console.WriteLine("After Long Process: " + i);
            return i;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var m = new MyClass();
            m.MainAsync();
            Console.WriteLine("Main done.");
        }        
    }
}

我得到的输出是:

Start MainAsync:1
In Something:2
After DoSomething: 1
Main done.
Press any key to continue . . .

这告诉我i = await t;正在将进程重新弹回Main,并且一旦完成任务就永远不会回来。

我做错了什么?

我正在寻找一个结果:

Start MainAsync:1
In Something:2
After DoSomething: 1
After Long Process: 2
Done waiting: 2
Main done.
Press any key to continue . . .

或者

Start MainAsync:1
In Something:2
After DoSomething: 1
Main done.
After Long Process: 2
Done waiting: 2
Press any key to continue . . .

感谢您的见解。

1 个答案:

答案 0 :(得分:6)

主方法完成后,您现在不再在程序中运行任何非后台线程,因此整个过程将结束。事实上,你的代码最终会在未来的某个时刻触发并不会改变它。

这就是为什么你通常会在应用程序的顶层有一个消息循环,能够接受和处理消息,并且如果当前没有消息要处理,则等待更多消息。由于运行消息泵的线程将是非后台线程,因此它不允许进程结束,直到整个循环关闭。