async和await不起作用

时间:2013-10-12 14:47:21

标签: c# .net asynchronous async-await

我正在尝试学习async并等待.NET 4.5的功能。首先,这是我的代码

    static async void Method()
    {
        await Task.Run(new Action(DoSomeProcess));
        Console.WriteLine("All Methods have been executed");
    }

    static void DoSomeProcess()
    {
        System.Threading.Thread.Sleep(3000);
    }

    static void Main(string[] args)
    {
        Method();
        //Console.WriteLine("Method Started");
        Console.ReadKey();
    }

此代码在控制台上没有给我任何结果。我不明白为什么。我的意思是不是任务假设只是没有阻塞的线程。但是,如果我取消注释main方法中的Console.WriteLine(),一切似乎都正常。

有谁能告诉我这里发生了什么?

2 个答案:

答案 0 :(得分:9)

使用async / await模式,有些东西与先前的线程不同。

  1. 你不应该使用System.Threading.Thread.Sleep 因为这仍然是阻塞的,不能用于异步。 而是使用Task.Delay

  2. 考虑让所有代码都异步。只有控制台中的Main方法不能异常原因

  3. 避免使用async void方法。基本上async void仅适用于无法返回某些内容的事件处理程序。所有其他异步方法应返回TaskTask<T>

  4. 修改了你的例子:

        static async Task Method()
        {
            await DoSomeProcess();
            Console.WriteLine("All Methods have been executed");
        }
    
        static async Task DoSomeProcess()
        {
            await Task.Delay(3000);
        }
    

    现在更改您的Main方法,因为这应该是您开始任务的地方

        Task.Run(() => Method()).Wait();
        //Console.WriteLine("Method Started");
        Console.ReadKey();
    

答案 1 :(得分:2)

学习如何正确使用asyncawait关键字有一个小的学习曲线。

问题在于没有人等待等待的人,还有一些其他详细信息,例如SyncronizationContextTask

你应该查看一些文章: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

要在Console中使用async和await关键字,您需要额外的代码: Can't specify the 'async' modifier on the 'Main' method of a console appAwait a Async Void method call for unit testingUnit Test Explorer does not show up Async Unit Tests for metro apps

我通常采用这种方法:

static void Main(string[] args)
{
    Console.WriteLine("HELLO WORLD");
    var t1 = Task.Factory.StartNew(new Func<Task>(async () => await Method()))
        .Unwrap();
    Console.WriteLine("STARTED");
    t1.Wait();
    Console.WriteLine("COMPLETED");
    Console.ReadKey();
}

static async Task Method()
{
    // this method is perfectly safe to use async / await keywords
    Console.WriteLine("BEFORE DELAY");
    await Task.Delay(1000);
    Console.WriteLine("AFTER DELAY");
}