我是 C# 异步编程的新手,需要看看以下哪种方式是处理 Task 对象的首选方式。
我有一个这样做的类:
var value = this.SomeFunction(...);
var innerValue = await Task.FromResult(value.Result);
Somefunction
看起来像下面。protected async Task<JObject> Somefunction(..)
{
..
returns JBoject
..
}
这按预期工作正常。现在,我有一个建议,我不应该使用
Task.FromResult
与 async
职能。相反,我应该使用类似的东西:
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 :
这个工作流程是制作 toast 的疯狂方式。它是有效的——最后你会得到一片 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/