为什么异步的返回类型必须为void,任务或任务< T> [英] Why return type of async must be void, Task or Task<T>

查看:243
本文介绍了为什么异步的返回类型必须为void,任务或任务< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的手脏与异步CTP和我注意到,编译器抱怨异步返回类型。什么是与其他类型的问题?

一个简单的演示

 静态无效的主要(字串[] args)
{
    做工作();
    Console.WriteLine(返回到主);
    Console.Read();
}

//为什么我需要返回void,任务或任务< T>这里?
//我知道我可以使用类似任务< IEnumerable的<字符串>>
私有静态异步的String []的D​​oWork()
{
    Console.WriteLine(DoWork的开始);
    返回等待Task.Factory.StartNew(
        代表
        {
            Thread.sleep代码(2000);
            Console.WriteLine(DoWork的完成);
            返回新的List<字符串>();
        });
}
 

解决方案

等待 [消费]方面,我们是灵活的:我们可以等待任何类型的,只要它 有正确的方法。

异步法[制作]一面,我们是不灵活的:我们是硬coded到 仅返回任务类型(或无效)。 为什么不一致?

  1. 迭代器已经具备了这种行为...

    这是迭代法(其中一个具有收益内)是硬codeD回任 的IEnumerable或IEnumerator的。 但是,您可以的foreach在任何类型的有 的GetEnumerator / MoveNext的/当前的成员。 因此,异步只是下面的套件。

  2. 任务就像是一个未来的,所以这是很好的硬code吧...

    一个任务是仅比未来更。 将来是一个语言/平台的一个基本的基本组成部分。 没有理由为一个语言两人这样一个基本的多个副本 概念。一个就够了。它是如此的基础,你甚至可以添加关键字到 语言处理期货。 无论如何,如果有人有未来性的东西,或任务更丰富的概念,那么他们可以 打造出来的任务或函数功能的。 (我们的任务已经在运行。如果你想建立的东西,就是冷,如F# asyncs或类似的IObservable,一种不启动,直到你告诉它 - 那么你应该 打造出来一个函数功能,而不是一项任务的)。

  3. 此外微妙

    定义这个功能:

     无效F< T>(Func键<任务< T>> F)
     

    和调用它:

      F(()=> 1 +等待T)
     

    我们希望能够推断出T = INT在这种情况下。这种推断是不可能的,除非 编译器硬codeD知识拉姆达它传递到F的类型为 任务< INT>

来源:<一href="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-12-06/4466.Technical-intro-to-the-Async-CTP.pdf"相对=nofollow> 技术介绍到异步CTP

I am trying get my hands dirty with async CTP and I noticed that the compiler complains about the async return type. What is the problem with other types?

A simple demo

static void Main(string[] args)
{
    DoWork();
    Console.WriteLine("Returned to main");
    Console.Read();
}

// why do I need to return void, Task or Task<T> here?
// I know I can use something like Task<IEnumerable<string>>
private static async string[] DoWork()
{
    Console.WriteLine("DoWork started");
    return await Task.Factory.StartNew(
        delegate
        {
            Thread.Sleep(2000);                
            Console.WriteLine("DoWork done");
            return new List<string>();
        });        
}

解决方案

On the await [consumption] side, we are flexible: we can await any type so long as it has the right methods.

On the async method [production] side, we are inflexible: we are hard-coded to return only the Task type (or void). Why the inconsistency?

  1. Iterators already have this behavior...

    An iterator method (one which has a "yield" inside) is hard-coded to return either IEnumerable or IEnumerator. However, you can "foreach" over any type which has GetEnumerator/MoveNext/Current members. So Async is just following suite.

  2. A task is like a future, so it’s good to hard-code it...

    A Task is barely more than a future. A future is a basic fundamental part of a language/platform. There’s no reason for a language two have multiple copies of such a fundamental notion. One is enough. It’s so foundational that you might even add keywords to the language to deal with futures. Anyway, if someone has a future-like thing, or a richer notion of task, then they can build it out of Task or Func. (Our Tasks are already running. If you want to build something that’s "cold", like F# asyncs or like IObservable, one which doesn’t start until you tell it – then you should build it out of a Func rather than out of a Task).

  3. Further subtleties

    Define this function:

    void f<T>(Func<Task<T>> f)
    

    And invoke it:

    f( () => 1 + await t )
    

    We’d like to be able to infer that T=int in this case. Such inference isn’t possible unless the compiler has hard-coded knowledge that the lambda it passes to "f" has type Task<int>.

Source: Technical intro to the Async CTP

这篇关于为什么异步的返回类型必须为void,任务或任务&LT; T&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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