2016-09-13 70 views
-3

这两个异步方法有什么区别?如果没有,这两种方法可以在哪种情况下有所不同?这两个异步方法有什么区别?

谢谢。

public async Task<int> MyMethod1Async() 
{ 
    return 1; 
} 

public async Task<int> MyMethod2Async() 
{ 
    return await new Task<int>(() => 1); 
} 
+2

由于没有异步代码,第一个不会是异步.... –

+2

我投票结束这个问题作为离题,因为关于异步/等待如何工作的基本问题是有价值的,但这种简化的形式是有缺陷的。即使指出重复的问题也很难,因为其中一个例子不是异步的。 – Guvante

+0

你什么时候真的在MyMethod2Async中运行任务?你只是创建一个新的任务。 – EJoshuaS

回答

1

考虑看看这两种方法:

public async Task<int> MyMethod1Async() 
{ 
    return 1; 
} 

这将同步运行,因为没有“等待”运营商在里面 - 它只是返回1,所以它是没有什么不同,如果你刚刚做的以下:

public int MyMethod1() 
{ 
    return 1; 
} 

以下的方法可能是不同的异步的“类型”之间的差的一个更好的说明:

public async Task<string> MyMethod1Async() 
    { 
     using (HttpClient client = new HttpClient()) 
     { 
      client.BaseAddress = new Uri("SomeBaseAddress"); 

      // This will return control to the method's caller until this gets a result from the server 
      HttpResponseMessage message = await client.GetAsync("SomeURI"); 

      // The same as above - returns control to the method's caller until this is done 
      string content = await message.Content.ReadAsStringAsync(); 

      return content; 
     } 
    } 

这样的代码不一定会产生额外的线程(除非这是微软恰巧实现了这些特定的库调用)。无论哪种方式,等待/异步确实不是需要创建额外的线程;它可以在同一个线程上异步运行。

我对这个事实的标准说明如下:假设你去一个有10个人的餐厅。当服务员过来时,他要求他的订单的第一个人还没有准备好;然而,其他9人是。因此,服务员要求其他9个人的命令,然后回到原来的家伙希望他会准备好订购。 (肯定不是这样,他们会得到第二个服务员等待原始人准备订购,而这样做可能不会节省太多时间)。这就是async/await在许多情况下的工作原理(例外是某些任务并行库调用,如Thread.Run(...),实际上在其他线程上执行 - 在我们的示例中,引入了第二个服务器 - 所以确保你检查哪些文件是哪个)。

你列出不会起作用,因为你刚才创建任务的下一个项目,你实际上并没有对它做任何事:

public async Task<int> MyMethod2Async() 
{ 
    return await new Task<int>(() => 1); 
} 

我假设你真正打算做类似的以下:

public async Task<int> MyMethod2Async() 
{ 
    return await Task.Run<int>(() => 1); 
} 

这将运行在线程池中的lambda表达式,返回控制MyMethod2Async的调用者,直到lambda表达式有一个结果,然后从lambda表达式返回值,一旦它确实有一个结果。

总而言之,不同之处在于你是否在同一个线程上异步运行(相当于桌子上的第一个人,告诉服务员在其他人订购后回到他身边),或者如果你正在运行任务在一个单独的线程上。

在过分简化事物的风险上,CPU绑定任务通常应该在后台线程上异步运行。但是,IO绑定任务(或其他情况下,holdup大多只是等待外部系统的某种结果)通常可以在同一个线程上异步运行;将它放在后台线程上与在同一线程上异步执行它们不会有太大的性能提升。

+0

谨慎解释downvote? – EJoshuaS

1

第方法返回的1一个Result一个已经完成的任务。

第二种方法返回永远不会完成的Task<int>