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

使用async await的方法的async await free等价物是什么?

  •  -1
  • sebrockm  · 技术社区  · 6 年前

    我试图理解,在c_中,一种使用 async await 在引擎盖下面。

    考虑以下两个例子:

    static async Task<byte[]> MyReadAsync1(Stream source)
    {
        var result = new byte[1024];
        int readBytes = 0;
    
        while (readBytes != result.Length)
        {
            int singleRead = await source.ReadAsync(result, readBytes, result.Length - readBytes);
            if (singleRead == 0)
                break;
            readBytes += singleRead;
        }
    
        if (readBytes == result.Length)
            return result;
        return result.Take(readBytes).ToArray();
    }
    
    static Task<byte[]> MyReadAsync2(Stream source)
    {
        return Task.Run(() =>
        {
            var result = new byte[1024];
            int readBytes = 0;
    
            while (readBytes != result.Length)
            {
                int singleRead;
                try
                {
                    singleRead = source.ReadAsync(result, readBytes, result.Length - readBytes).Result;
                }
                catch (AggregateException e)
                {
                    ExceptionDispatchInfo.Capture(e.InnerException).Throw();
                }
    
                if (singleRead == 0)
                    break;
                readBytes += singleRead;
            }
    
            if (readBytes == result.Length)
                return result;
            return result.Take(readBytes).ToArray();
        });
    }
    

    我的问题是:这两种方法是等价的吗?

    如果我处决他们,看起来他们是。它们都没有阻塞调用线程。据我所知,他们正在做着完全相同的事情,即使有任何异常被抛出。

    如果它们真的是等价的,编译器会产生相同的代码吗?那是不是意味着 异步等待 除了保存一些样板代码,启动一个任务并展开aggregateexceptions之外,别无他用吗?

    如果存在差异,那么它到底是什么?如果没有 异步等待 ?

    注:我看到了这个问题 What is the purpose of “return await” in C#? 我理解这里给出的答案。但这只涉及一个返回语句的情况,而我的问题是为了更一般。

    我不是在质疑 异步等待 ,我只是想详细了解一下。

    更新

    这个 possible duplicate 不回答我的问题。这个问题只涉及一行代码,比较 .Result await . 在我的问题中,我有许多附加代码行,它们与异步代码“混合”在一起,并且 MyReadAsync2 方法我将整个执行过程包装为 Task.Run . 我看不出另一个问题是如何解决这些附加问题的。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Damien_The_Unbeliever    6 年前

    粗略 如果你想写一个 async 免费版本的代码,你将使用 ContinueWith 在几乎相同的位置 await ,而不是使用 Result (如前所述,将阻止 可能导致死锁)。

    当然,这会忽略同步上下文机制,例如,如果调用了原始方法的上下文,则可以使代码在ui线程上运行。你也会发现 等待 )你的嵌套级别变得疯狂,你不能很容易地使用一些结构(例如,尝试做一个 等待 在循环中,然后尝试使用 继续 1,2 )

    有很多机器 异步的 / 等待 只要给你,你就不必经常在幕后偷看。如果你想的话,你可以试着编译一些 异步的 基于代码,然后通过不支持 异步的 或者可以不尝试逆向工程 异步的 方法。


    不是那么简单的循环 只是 打电话 等待 是一个很好的典型例子 异步的 代码在大多数情况下。

    注意,在这个例子中,循环的每个迭代只在前一个可等待的完成时开始,因此您必须通过 循环上下文 不管你用什么方法 小精灵 打电话。