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

跳过await是否自动使异步代码同步?

楚宪
2023-03-14

假设我有以下内容:

void SaveImage(Texture tex, string path)
{
    WritePngAsync(tex, path);
}

public static async void WritePngAsync(Texture tex, string path)
{
    // This code takes a long time to execute
    await PNG.WriteAsync(texture, path);
}

然后我这样称呼它:

for (int i = 0; i < 3; i++)
{
    var imageData = createData();// Create image data somehow
    SaveImage(imageData, $"{i}.png");
}

我省略了await并且没有将saveimage声明为async这一事实是否使它实际上是异步的?

我希望发生的情况是循环会立即完成,因为即使WritePngasync花费了很长时间,SaveImage也不会被等待,并且会立即返回。

我认为这会导致文件内容在这样调用时被覆盖的问题,但这使我认为代码是以某种方式自动转换为同步代码的(尽管似乎不可能知道writeasync何时完成)。

那么,简单地说,从非异步方法调用autited函数是否会自动使代码同步执行,以及省略asyncawait(如在saveimage函数中省略asyncawait会有什么潜在问题。

共有1个答案

曹鹏海
2023-03-14

我省略了await并且没有将SaveImage声明为async这一事实是否使它实际上[synchronou]?

不,Async void方法由于几个原因是危险的。它们是异步的,但是您的代码没有办法检测异步操作何时完成。此外,由于您的代码无法检测异步操作中的错误,因此任何异常都将直接在当前上下文中引发,这通常会导致应用程序关闭。这种行为看起来非常奇怪而且不可取,直到您意识到async void方法是专门设计用来用作事件处理程序的,在其他情况下应该避免使用。

我希望发生的是,循环会立即完成,因为即使WritePngAsync花费了很长时间,SaveImage也不会被等待,并且会立即返回。

是的,循环很快完成,并且当循环完成时,所有png.writeasync操作可能都不完整。

我认为这会导致文件内容在这样调用时被覆盖的问题

听起来很合理。您的代码无法知道writePngasync方法何时完成。

 类似资料:
  • 问题内容: 我们正在与节点合作,主要用于内部项目,并了解使用该技术的最佳方法。 并非来自特定的异步背景,学习曲线可能是一个挑战,但是我们已经习惯了框架和学习过程。 使我们两极分化的是,何时才是使用同步代码与异步代码的最佳时间。我们目前使用的规则是,如果任何东西与IO进行交互,那么它必须通过回调或事件发射器(即给定的)是异步的,但是可以将任何未使用IO的其他项构造为同步函数(此方法还将取决于函数本身

  • 函数recursive 是异步加递归 理想状态是:在函数updateParams调用 await函数recursive执行完后再执行后面代码。 实际:函数recursive还没执行完后面的代码就执行了

  • 当我在阅读有关承诺的文章时,我知道当我使用async/Await时,我可以同步打印承诺(在本例中为print:first,second,third,last to print)。现在我也读到了使用链接和异步/等待也可以达到同样的目的。然而,当我试图将我的承诺链接起来时,除了“最后一次打印”的console.log之外,什么也没有发生。任何洞察力都会很棒!谢谢!! 编辑到问题: 日志: 1:如果传递

  • 我如何做到这一点?还是我理解了一些根本错误的东西? 后果 预期结果

  • 使用Mocha测试异步代码并不简单!只需在测试完成后调用回调。通过添加一个回调(通常命名done)it(),Mocha将知道它应该等待调用此函数来完成测试。此回调接受Error实例(或其子类)或伪值; 其他任何事情都会导致测试失败。 describe('User', function() { describe('#save()', function() { it('should save wi