代码之家  ›  专栏  ›  技术社区  ›  zildjohn01

C 5.0的异步等待特性与TPL有何不同?

  •  61
  • zildjohn01  · 技术社区  · 14 年前

    我看不出C(和VB)的新异步功能与.NET 4.0的不同。 Task Parallel Library . 以埃里克·利珀特的代码为例 from here :

    async void ArchiveDocuments(List<Url> urls) {
        Task archive = null;
        for(int i = 0; i < urls.Count; ++i) {
            var document = await FetchAsync(urls[i]);
            if (archive != null)
                await archive;
            archive = ArchiveAsync(document);
        }
    }
    

    似乎 await 关键字有两个不同的用途。第一次出现( FetchAsync )似乎是说, “如果使用此值 后面的方法 它的任务没有完成,请等到它完成后再继续。” 第二个实例( archive )似乎是说, “如果此任务尚未完成,请等待 马上 直到完成。” 如果我错了,请纠正我。

    难道就不能这么容易地写吗?

    void ArchiveDocuments(List<Url> urls) {
        for(int i = 0; i < urls.Count; ++i) {
            var document = FetchAsync(urls[i]);       // removed await
            if (archive != null)
                archive.Wait();                       // changed to .Wait()
            archive = ArchiveAsync(document.Result);  // added .Result
        }
    }
    

    我换了第一个 等待 用一个 Task.Result 在实际需要值的地方,以及第二个 等待 具有 Task.Wait() ,实际发生等待的位置。功能是 (1) 已经实施,以及 (2) 在语义上更接近代码中实际发生的事情。

    我确实意识到 async 方法被重写为一个状态机,类似于迭代器,但我也不知道它带来了什么好处。任何需要另一个线程操作的代码(如下载)仍然需要另一个线程,而任何不需要的代码(如从文件中读取)仍然可以使用TPL只使用一个线程。

    我显然错过了一些重要的东西;有人能帮我更好地理解这一点吗?

    7 回复  |  直到 7 年前
        1
  •  71
  •   Cœur Gustavo Armenta    7 年前

    var document = await FetchAsync(urls[i]);
    

    Task<T>

        2
  •  25
  •   Daniel    14 年前

    Wait() await ArchiveDocuments()

    async ArchiveDocuments

        3
  •  24
  •   Brad Cunningham    14 年前

        4
  •  6
  •   John Leidegren    14 年前
        5
  •  4
  •   JaredPar    14 年前

    ArchiveDocuments void Task

    async Task ArchiveDocuments(List<Url> urls) { 
      ...
    }
    

        6
  •  0
  •   James King    14 年前

    FetchAsync() await ArchiveDocuments async

    ArchiveAsync()

    await archive Task