当前位置: 首页 > 知识库问答 >
问题:

wait/async与线程有何不同?

黄沈浪
2023-03-14

我正在尝试熟悉c#的新Wait/async关键字,我发现了几个我不太了解的方面。

>

  • 让我们从比赛条件开始:

    Stream s=...
    ...
    for(int i=0;i<100;i++)
    {
        s.WriteAsync(new byte[]{i},0,1);
    }
    

    这是否会一直按预期工作(例如写入文件12345......而不是13254之类的)?

    第二件事是,如果异步函数不包含await运算符,它将同步执行。而且,根据microsoft文档,异步函数总是在调用线程中执行(与BeginInvoke相比)。接下来我要问3个问题:

    异步函数在释放到调用方函数之前执行了多少?

    async void MyAsyncFunction()
    {
        Operation1();
        Operation2();
        Operation3();
        ....
        Stream s=...;
        await s.WriteAsync(....);
    }
    

    在我读过的关于await/async的文章中,有人说没有await操作符的异步函数是按顺序执行的,而带有async/await的函数很快就会返回。但让我烦恼的是,MyAsyncFunction可能总是执行操作1。。。操作3在点击时释放,等待s.WriteAsync。

    如果我使用线程怎么办。在异步函数中睡眠,如下所示:

    async void DoStuff()
    {
        Stream s=...;
        ...
        await s.WriteAsync(....);
        Thread.Sleep(10000);
        ....
    }
    

    将线程。睡眠阻塞执行它的整个线程还是仅阻塞异步函数?

    如果我使用信号量怎么办。在一个异步函数中等待(),它会期望信号量由另一个异步函数释放。这会像线程一样,还是会导致死锁?

    Wait在异步函数之外不起作用。为什么?

  • 共有3个答案

    潘宸
    2023-03-14

    简而言之,答案似乎是“非常”。虽然以下可能无法回答您的所有问题,但我认为它适用于一个足够通用的用例。考虑您的Stream而不是他们所指的网络IO。

    在重叠网络IO的情况下,将使用IO完成端口,回调由硬件中断触发。

    这意味着当我们“等待”完成时,线程不会被消耗。[...]

    可以在一个线程上执行所有操作。[...] 然而,这将取决于平台,即“等待者”实现

    http://social.msdn.microsoft.com/Forums/en-US/async/thread/a46c8a54-f8d4-4fa9-8746-64d6a3a7540d/

    东门秦迟
    2023-03-14

    您可以在Eric Lippert的以下帖子中找到有关等待操作员的问题的答案,他说:

    “await”操作符…并不意味着“此方法现在阻止当前线程,直到异步操作返回”。这将使异步操作变回同步操作,这正是我们试图避免的。相反,它的意思是相反的;这意味着“如果我们正在等待的任务尚未完成,请将此方法的其余部分注册为该任务的延续,然后立即返回给调用者;任务完成后将调用延续。--Eric Lippert

    微生鸿轩
    2023-03-14

    我建议您阅读我的异步简介。

    这是否会一直按预期工作(例如,写入文件12345…而不是13254或其他文件)?

    不,您需要等待WriteAsync的调用。

    异步函数在释放到调用方函数之前执行了多少?

    直到它等待是一个尚未完成的操作。

    将线程。睡眠阻塞执行它的整个线程还是仅阻塞异步函数?

    线程。睡眠-和所有其他阻塞方法-将阻塞async方法和正在执行它的线程。

    一般来说,不要在异步方法中使用任何阻塞方法。

    如果我在其中一个异步函数中使用信号量呢。等待(),它会期望信号量被另一个异步函数释放。这会像线程一样,还是会导致死锁?

    这完全取决于你的上下文。等待是一个阻塞方法,所以如果“其他”async方法需要阻塞方法保存的上下文,那么你就会死锁。

    请注意,信号量lim是异步的;您可以使用WaitAsync代替Wait。

    await在异步函数之外不起作用。为什么?

    因为关键字async启用了关键字wait。这样做是为了尽量减少新关键字对C语言的影响,并提高代码的可读性。

     类似资料:
    • 在我的ReactJS项目中,我一直在使用AsyncWait和babel。我发现React setState有一个方便的用法,我只是想更好地理解它。考虑这个代码: 我的意图是让异步验证代码在组件更新后运行。它工作了!生成的控制台日志显示: 验证代码仅在handleChange更新状态并呈现新状态后运行。 通常,要在状态更新后运行代码,必须在this.set状态后使用回调。这意味着如果你想在handl

    • 我正在构建一个endpoint/用户,它将返回用户中的内容。json文件。我正在使用aysnc/等待功能。 这会引发以下错误 语法错误:意外标记( 在对象上的createScript(vm.js:56:10)。在模块处运行InthisContext(vm.js:97:10)_在对象处编译(module.js:542:28)。模块_扩展。。模块处的js(模块js:579:10)。在函数tryModu

    • 本文向大家介绍Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll),包括了Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)的使用技巧和注意事项,需要的朋友参考一下 本篇我们来研究一下 wait() notify() notifyAll() 。 DEMO1: wait() 与 notify() DEMO1 输出: 注意: 使用 wait

    • 问题内容: 我需要使线程顺序。他们需要按以下顺序启动: 当D完成时,C可以完成,然后B,然后是A。 在这种情况下,最好使用线程或?为什么呢? 我的线程需要启动并打印消息,完成后需要打印。 问题答案: 由于您正在等待“其他”线程完成(即完成执行),因此是更好的选择。 的javadoc 简单地说: 等待该线程死亡。 然后,该机制相对简单: 要说明:您需要参考。因此,指向,指向,指向和不指向任何对象(它

    • 想改进这个问题吗 通过编辑此帖子,更新问题,使其只关注一个问题。 我试图理解Wait async在C中是如何工作的,有一件事让我很困惑。我知道任何使用await关键字的方法都必须标记为async。我的理解是,当命中带有await关键字的行时,该行下面的代码不会执行。启动异步操作以在等待行中执行语句,并将控件返回给可以继续执行的调用方法。 问题#1:这个假设是正确的还是wait关键字下面的代码仍在执

    • 问题内容: 基本上我需要在更多线程中运行〜数百个计算。我只想在paralell中运行一些并行线程,例如5个线程和5个计算。 我正在使用spring框架,@Async选项是自然选择。我不需要全功能的JMS队列,这对我来说有点麻烦。 有任何想法吗 ?谢谢 问题答案: 你检查了吗?你可以定义一个线程池,其中包含最大数量的线程来执行任务。 如果要与结合使用,请在spring-config中使用它: