2013-02-07 159 views
3

我使用Microsoft.Bcl.Async NuGet包使用异步/等待(我的目标是.NET 4.0,而不是4.5)混淆了.NET 4异步

我是新来的异步/等待。下面的代码示例描述了我的问题。为什么突出显示的行不被调用?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace AsyncTest 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Run(); 

     Console.WriteLine("Got the value"); 

     Console.ReadKey(); 
    } 

    public static async void Run() 
    { 
     Console.WriteLine("Testing Async..."); 

     var val = await AsyncMethod(); 

     // HIGHLIGHTED LINE. WHY IS THIS LINE NOT CALLED? 
     Console.WriteLine("And the value is... {0}", val); 
    } 

    public static Task<long> AsyncMethod() 
    { 
     long myVal = 1; 

     for (long l = 0; l < 100000; l++) 
     { 
      myVal++; 
      Console.WriteLine("l = {0}", l); 
     } 

     return new Task<long>(() => myVal); 
    } 
} 
} 
+0

这不是原因,但您需要将循环放入任务 – gabba

回答

5

线:

Console.WriteLine("And the value is... {0}", val); 

转换(由编译器)成延续;只有当正在等待的任务完成时才会被调用(使用值等)。问题是:你创建了一个任务,但你没有开始它:所以它永远不会完成。

如果你开始你在底部创建的任务,它最终会完成。此外,通常你会放在“做”工作Task - 不是外面:

public static Task<long> AsyncMethod() 
    { 
     var task = new Task<long>(() => 
     { 
      long myVal = 1; 

      for (long l = 0; l < 100000; l++) 
      { 
       myVal++; 
       Console.WriteLine("l = {0}", l); 
      } 
      return myVal; 
     }); 
     task.Start(); 
     return task; 
    } 

还要注意的是Got the value被打印出来And the value is...前 - 那是因为延续发生工作线程上的; Run方法在第一个await将控制权返回给调用者(Main)。

+2

您没有使用Task.Factory.StartNew或Run的任何原因? – usr

+0

谢谢,这很有道理! – rhughes

-1

您不应将其称为“AsyncMethod”,因为它没有异步元素。

该方法使用将在当前线程的单独线程中运行的任务。