RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 798810
Accepted
Snuppi
Snuppi
Asked:2020-03-16 00:08:37 +0000 UTC2020-03-16 00:08:37 +0000 UTC 2020-03-16 00:08:37 +0000 UTC

解析异步等待[重复]

  • 772
这个问题已经在这里得到了回答:
您是否需要异步/等待? (5 个回答)
4年前关闭。

您好,对于这个话题的问题,我很抱歉,因为关于这些关键字的文章数量相当多,但也许这么多的文章让我陷入了某种误解。

我只想知道我是否正确理解了所有内容,并向竞选活动提出了几个问题。

  1. 让我们从async开始。标记为 async 的方法允许我们在此方法中使用 await,并要求返回类型具有 GetAwaiter 方法。
  2. 等待关键字。Await 放在辅助线程中执行的操作之前。它允许您不要等到辅助线程(IO 或常规线程)完成其执行。Await 只是将 await 之后的内容包装在一个单独的方法中,该方法在辅助线程完成时由回调调用。因此,主线程继续进一步执行。并且当辅助线程完成后,会从线程池中随机取出一个线程,完成方法的第二部分。

总的来说,它在应用程序中提供了什么

  • 在带有 ui 线程的应用程序中(不完全清楚什么样的 ui 线程,我只使用 asp.net),我们的线程将继续运行并且不会阻塞用户操作;
  • 在 asp.net mvc 中,我的主线程将被释放,只有辅助线程可以工作;
  • 以及隐藏所有执行此操作的逻辑的最后一个语法糖。

问题

  1. 我是否正确描述了所有内容,这真的是异步等待的重点吗(将方法分成两部分并将第二部分作为回调执行,从而不会延迟主线程)?
  2. 什么是configureawait方法?
  3. 为什么很多人说这些关键词与流无关。那么,如何将 await 放在将在辅助线程中执行的操作之前,关键是,这种设计是为了不保留主线程而发明的。所以这里的联系是最直接的还是我错了?
  4. 当辅助线程完成执行时,哪个线程将继续执行方法的第二部分。同一个二级流?或者线程池中的任何线程都会被占用吗?
c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    VladD
    2020-03-16T00:35:54Z2020-03-16T00:35:54Z

    首先,你的假设。

    1. 嗯,从技术上讲,是的。但是还有一件更重要的事情要理解:使用关键字,async函数被分成几部分,因此在这些部分之间,函数根本不会在任何地方运行。并且每个部分都是同步执行的,就像一个普通的函数一样。这些碎片的边界是沿着await。

    2. “等待被放置在在辅助线程上运行的操作之前。” - 这是不正确的,await它仅表示此时函数停止执行,并Task在与其执行相关await的 结束时恢复。

      Task,正如我们已经看到的,根本不意味着“在某个线程中运行的一段代码”。例如,async-function 产生Task,它只是偶尔在特定线程中以块的形式运行。


    现在,你的问题。

    1. 一般来说,是的,但不是在一个部分,而是在许多方面。例如,想象一下这段代码:

      async Task PrintSlowly(IEnumerable<int> data)
      {
          Console.WriteLine("begin");
          foreach (var n in data)
          {
              await Task.Delay(1000);
              Console.WriteLine(data);
          }
          Console.WriteLine("end");
      }
      

      在这个方法中,我们有k + 1一个块,其中k是从 中获取的元素的数量IEnumerable<int>。

    2. 如果await在 UI 线程(或在任何拥有自己的TaskScheduler/的线程上SynchronizationContext)执行,则函数的下一部分将被扔到同一个 / 线程执行SynchronizationContext。如果你不需要它,你可以说ConfigureAwait(false),这意味着“我不在乎async-function 的其余部分在什么上下文中运行”。同时,运行时可以让它们在任何地方运行,没有任何保证。

    3. 不,完成的操作await不一定会在不同的线程上执行。Task不是“在其他地方执行的一段代码”。如果这个操作实际上并没有阻塞当前线程,那么是的,当前线程将是空闲的。但是您可以轻松编写Task,这将阻塞当前线程:

      async Task Weird()
      {
          if (Math.Sin(0) == 42)
              await Task.Delay(1000);
          for (int x = 0; x < 1_000_000; x++)
          for (int y = 0; y < 1_000_000; y++)
          for (int z = 0; z < 1_000_000; z++)
          {
              if (x * x * x * x + y * y * y * y == z * z * z * z)
                  throw new Exception("Ферма лох");
          }
      }
      
    4. 在哪里以及如何进行Task,完全由他自己决定Task。Task它完全在侧线程上执行的唯一情况是Task运行时Task.Run()(在这种情况下,线程是从线程池中获取的)。在其他情况下,决定在哪里执行是Task'e'的责任, async/await不关心它,甚至不要求Task它在任何地方执行。Task应该完成,是的(即使这样也不是必需的),但它可以在任何地方执行。这是一个例子:

      static Task WaitTimer()
      {
          var tcs = new TaskCompletionSource<int>();
          new System.Threading.Timer(o => tcs.SetResult(0), null, 3000,
                                     System.Threading.Timeout.Infinite);
          return tcs.Task;
      }
      

    是的,一定要阅读这个问题的答案。

    • 5

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5