c# - 在 C# 中使用 Task.FromResult v/s await

标签 c# asynchronous async-await task

我是 C# 异步编程的新手,需要看看以下哪种方式是处理 Task 对象的首选方式。

我有一个这样做的类:

var value = this.SomeFunction(...);

var innerValue = await Task.FromResult(value.Result);
Somefunction看起来像下面。
protected async Task<JObject> Somefunction(..)
{
 ..
 returns JBoject
 ..
}

这按预期工作正常。现在,我有一个建议,我不应该使用 Task.FromResultasync职能。
相反,我应该使用类似的东西:
var innerValue = await value; //..this works fine too

但我不确定为什么第一个不是完成同样事情的好习惯 .
任何线索都会有所帮助。
谢谢

最佳答案

让我们来看看你在做什么,并准确地说明为什么它是错误的。

var value = this.SomeFunction(...);

首先:使用 var当类型明确或不重要时。 类型在这里不清楚,很重要 .

第二:命名与 Async 异步的函数后缀。

让我们修正你的例子。它仍然是错误的,但现在更清楚了:
Task<Toast> toastTask = this.StartToasterAsync();
Toast toast = await Task.FromResult(toastTask.Result);

这个工作流程是完全错误的。 让我们把它翻译成英文。这是我今天的待办事项 list :
  • 在 toastr 里放一些面包。
  • toast 时,我可以做其他工作,但是,盯着 toastr 做其他事情,直到它完成 .
  • 从 toastr 中取出 toast ,然后开始一个新的待办事项列表。
  • 新的待办事项 list 是:拿到我现在拿着的那块 toast 。
  • 执行该待办事项列表。在等待待办事项列表完成的同时,去做其他工作,但待办事项列表总是已经完成,因为工作是获得我已经获得的结果 .所以不要做其他工作。检查一下,是的,我实际上拿着我刚刚写了一份待办事项 list 的那块 toast 。
  • 现在我有一片 toast 。

  • 这个工作流程是制作 toast 的疯狂方式。它是有效的——最后你会得到一片 toast ——但没有明智的人会这样做,你不应该编写等效的计算机程序:
  • 这是一个“异步”工作流,其中 消除了所有可能的异步优势 .
  • 第一步——等待 toastr 弹出——已经同步等待。
  • 第二步——异步等待一个已经完成的任务——绝不是异步的!

  • 永远永远永远永远不要以这种方式编写异步代码。

    制作 toast 的正确工作流程是:
  • 将面包放入 toastr ,开始烘烤。
  • 做其他工作直到 toast 爆裂。
  • 拿来 toast 。

  • 正如我们所期望的,编写程序的正确方法要简单得多:
    Task<Toast> toastTask = this.StartToasterAsync(...);
    Toast toast = await toastTask;
    

    或者甚至更好:
    Toast toast = await this.StartToasterAsync(...);
    

    您对此不熟悉,还没有内化异步工作流上各种操作的含义。你的小程序中的操作是:
  • .Result意味着停止异步并且在结果可用之前什么都不做。请注意 这会导致死锁 .您正在停止线程,直到结果可用; 如果您要停止将来会产生结果的线程会怎样 ?想象一下,例如我们做了一个待办事项列表“(1)从互联网上订购一盒巧克力。(2)在巧克力到达之前什么都不做。(3)从邮箱中取出巧克力。”该工作流未完成,因为有一个同步等待结果,需要您在 future 进行工作。
  • await意味着此工作流在结果可用之前无法继续,因此异步等待它。去寻找其他的工作要做,当结果出来时,我们会从这里重新开始。

  • 请注意,它们都意味着相同的事情,因为两者都是工作流中的点,在该点上,工作流在结果可用之前不会继续。但它们完全不同的地方在于Result是同步等待,而 await是一个异步等待。 确保您理解这一点 .这是您必须了解的最基本的一点。

    最后
  • FromResult意味着有人需要一个任务,但我已经有了那个任务的结果,所以做一个已经完成的任务。当它是await ed 或当 Result对其调用,无论哪种方式,它都会立即返回结果。

  • 打电话不寻常FromResult .如果您处于异步工作流中,通常您只需 return result;表示任务已完成。

    关于c# - 在 C# 中使用 Task.FromResult v/s await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50726867/

    相关文章:

    c# - MEF - 是否必须以某种方式设置导入或者它们可能为空?

    unit-testing - react 堆项目 : wait while broadcaster finish

    javascript - 如何构建异步函数的测试?

    rust - 如何在异步函数中设置断点?

    node.js - 与nodejs和sqlite3同步的SELECT查询

    c# - 如何使 Dispose 等待所有异步方法?

    c# - 如果使用 Visual C++ Compiler November 2013 CTP,所有依赖项是否也需要用它编译?

    c# - 我缺少什么来使用嵌入式资源?

    c# - 使用 lambda 查询获取前 5 个值

    Android:处理回调结果以避免崩溃的最佳方法?