lea*_*arn 2 c# asynchronous task async-await
我是C#异步编程的新手,需要查看以下哪个是处理Task对象的首选方法.
我有一个类这样做:
var value = this.SomeFunction(...);
var innerValue = await Task.FromResult(value.Result);
Run Code Online (Sandbox Code Playgroud)
Somefunction 看起来如下.
protected async Task<JObject> Somefunction(..)
{
..
returns JBoject
..
}
Run Code Online (Sandbox Code Playgroud)
这可以正常工作.现在,我有我不应该使用的建议Task.FromResult与async功能.相反,我应该使用类似的东西:
var innerValue = await value; //..this works fine too
Run Code Online (Sandbox Code Playgroud)
但我不确定为什么第一个不是一个很好的做法来完成同样的事情.任何线索都会有所帮助.谢谢
Eri*_*ert 25
让我们来看看你正在做的事情并准确地说出它为什么是错的.
var value = this.SomeFunction(...);
Run Code Online (Sandbox Code Playgroud)
首先:var当类型清晰或不重要时使用. 这种类型在这里并不清楚,这很重要.
第二:与Async后缀异步的名称函数.
让我们来解决你的例子吧.它仍然是错的,但现在更清楚了:
Task<Toast> toastTask = this.StartToasterAsync();
Toast toast = await Task.FromResult(toastTask.Result);
Run Code Online (Sandbox Code Playgroud)
这个工作流程完全错误. 我们把它翻译成英文.这是我今天的待办事项列表:
这个工作流程是制作吐司的疯狂方式.它的工作原理 - 你最后得到了一片吐司 - 但没有明智的人会这样做,你不应该写相同的计算机程序:
绝不永远不会以这种方式编写异步代码.
制作一片吐司的正确工作流程是:
正如我们所期望的,编写程序的正确方法要简单得多:
Task<Toast> toastTask = this.StartToasterAsync(...);
Toast toast = await toastTask;
Run Code Online (Sandbox Code Playgroud)
甚至更好:
Toast toast = await this.StartToasterAsync(...);
Run Code Online (Sandbox Code Playgroud)
您是新手,并没有内化异步工作流上各种操作的含义.您的小程序中的操作是:
.Result意味着停止异步,并在结果可用之前不执行任何操作.请注意,这可能会导致死锁.您正在停止一个线程,直到结果可用; 如果你要停止将来会产生结果的线程怎么办?想象一下,例如我们做了一个待办事项清单"(1)从互联网上订购一盒巧克力.(2)在巧克力到货之前什么也不做.(3)从巧克力中取出巧克力." 该工作流程未完成,因为同步等待结果需要您将来继续工作.await表示此工作流无法继续,直到结果可用,因此异步等待它.下去找其他工作要做,当结果可用时,我们将在这里重新开始.请注意,它们都意味着相同的事情,因为两者都是工作流中的点,在结果可用之前工作流不会继续.但他们是完全不同的在Result是同步的等待,并且await是一个异步等待. 确保你明白这一点.这是您必须了解的最基本点.
最后
FromResult意味着某人需要一项任务,但我已经拥有该任务的结果,因此请完成一项已经完成的任务.当它被await编辑或何时Result被调用时,无论哪种方式,它都会立即返回结果.打电话是不寻常的FromResult.如果您处于异步工作流程中,通常只是return result;表示任务已完成.