在C#中使用Task.FromResult v/s等待 [英] Using Task.FromResult v/s await in C#

查看:87
本文介绍了在C#中使用Task.FromResult v/s等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to C# async programming and need to see if which of the following is a preferred way to deal with Task object.

我有一个可以做到这一点的班级

I have a class that does this:

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

var innerValue = await Task.FromResult(value.Result);

某些功能如下所示.

protected async Task<JObject> Somefunction(..)
{
 ..
 returns JBoject
 ..
}

这按预期工作正常.现在,我建议我不要将 Task.FromResult async 函数一起使用.相反,我应该使用类似这样的东西:

This works fine as expected. Now, I have a suggestion that I shouldn't be using Task.FromResult with async functions. Instead, I should be using something like:

var innerValue = await value; //..this works fine too

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

But I am not really sure why the 1st one isn't a good practice to get the same thing done. Any leads would be helpful. Thanks

推荐答案

让我们仔细研究一下您正在做的事情,并精确地说出为什么它是错误的.

Let's go through what you're doing and say precisely why it is wrong.

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

首先,当类型为clear或不重要时,请使用 var .这里的类型不清楚,很重要.

First off: use var when the type is either clear or unimportant. The type is not clear here and it is important.

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

Second: Name functions that are asynchronous with an Async suffix.

让我们修正您的示例.仍然是错误的,但是现在更清楚了:

Let's fix up your example. It's still wrong, but now it is more clear:

Task<Toast> toastTask = this.StartToasterAsync();
Toast toast = await Task.FromResult(toastTask.Result);

此工作流程完全错误.让我们将其翻译为英语.这是我今天的待办事项清单:

This workflow is completely wrong. Let's translate it into English. Here's my to-do list for today:

  • 在烤面包机中放一些面包.
  • 虽然面包在烤面包,我本来可以做其他工作,但是,凝视烤面包机,直到面包做完为止.
  • 从烤面包机中获取烤面包,并开始一个新的待办事项清单.
  • 新的待办事项清单是:获取我现在拿着的一块吐司.
  • 执行该任务清单.在我等待待办事项清单完成的同时,去做其他工作,但是待办事项清单始终已经完成,因为工作是要获得我已经获得的结果.所以不要做其他工作.只需检查是,我实际上就拿着刚刚写了一份待办事项清单的吐司.
  • 现在我要烤面包.
  • Put some bread in the toaster.
  • While the bread is toasting I could be doing other work, but instead, stare at the toaster doing nothing else until it is done.
  • Get the toast from the toaster, and start a new to-do list.
  • The new to-do list is: Obtain the piece of toast that I am now holding.
  • Execute that to-do list. While I'm waiting for the to-do list to complete, go do other work, but the to-do list is always already complete because the job is to obtain a result that I have already obtained. So don't do other work. Just check that yes, I am in fact holding the piece of toast I just wrote a to-do list about.
  • Now I have a piece of toast.

此工作流程是一种疯狂的烤面包方式.它行之有效-最后您要吃一片吐司-但没有明智的人会这样做,并且您不应该编写等效的计算机程序:

This workflow is an insane way to make toast. It works -- you end up with a piece of toast at the end -- but no sensible person would do this, and you should not write the equivalent computer program:

  • 这是一个异步"工作流程,其中所有可能的异步优势都已被删除.
  • 第一步-等待烤面包机弹出-已同步等待.
  • 第二步-异步等待已完成的任务-绝不异步!

永远不会永远不会以这种方式编写异步代码.

Never never never write asynchronous code this way.

做烤面包片的正确工作流程是:

The right workflow for making a piece of toast is:

  • 将面包放入烤面包机中,开始烘烤.
  • 做其他工作,直到烤面包吐司.
  • 拿面包.

正如我们期望的那样,编写程序的正确方法要简单得多:

And as we'd expect, the correct way to write your program is much simpler:

Task<Toast> toastTask = this.StartToasterAsync(...);
Toast toast = await toastTask;

甚至更好:

Toast toast = await this.StartToasterAsync(...);

您是新手,还没有内部化异步工作流上各种操作的含义.您的小程序中的操作是:

You're new to this and you have not internalized the meanings of the various operations on asynchronous workflows. The operations in your little program are:

  • .Result 表示停止异步并且在结果可用之前不执行任何操作.请注意,这可能会导致死锁.您正在停止线程,直到结果可用为止.如果您要停止将来将要产生结果的线程,该怎么办?想象一下,例如,我们做了一个待办事项清单,(1)从互联网订购一盒巧克力.(2)在巧克力到达之前什么也不做.(3)从邮箱中取出巧克力."该工作流程未完成,因为需要同步等待结果,要求您将来进行 .
  • await 表示在结果可用之前,该工作流程无法继续,因此请异步地等待它.离开并找到其他工作要做,待结果可用后,我们将从这里重新开始.
  • .Result means stop being asynchronous and do nothing until the result is available. Note that this can cause deadlocks. You are stopping a thread until the result is available; what if you are stopping the thread that was going to produce the result in the future? Imagine for instance that we did a to-do list of "(1) Order a box of chocolates from the internet. (2) Do nothing until the chocolates arrive. (3) Get the chocolates out of the mailbox." That workflow does not complete because there is a synchronous wait for a result that requires you to do work in the future.
  • await means this workflow cannot continue until the result is available so asynchronously wait for it. Go off and find other work to do, and when the result is available, we'll start again here.

请注意,这两者都是同一件事,因为都是工作流中的点,在这些点上,直到结果可用,工作流才继续进行.但是它们完全不同,因为 Result synchronous 等待,而 await asynchronous 等待.确保您了解这一点.这是您必须了解的最基本的观点.

Note that both of them mean the same thing, in that both are points in a workflow where the workflow does not proceed until the result is available. But they are completely different in that Result is a synchronous wait, and await is an asynchronous wait. Make sure you understand this. It is the most fundamental point that you must understand.

最后

  • FromResult 表示有人需要一个任务,但是我已经有了该任务的结果,所以要完成一个已经完成的任务.当 await 或调用 Result 时,无论哪种方式,它都会立即返回结果.
  • FromResult means someone needs a task, but I already have the result of that task, so make a task that is already complete. When it is awaited or when Result is called on it, either way, it returns the result immediately.

调用 FromResult 是不寻常的.如果您处于异步工作流程中,通常只需返回结果; 即可表示任务已完成.

It is unusual to call FromResult. If you are in an asynchronous workflow, normally you would just return result; to signal that a task was complete.

这篇关于在C#中使用Task.FromResult v/s等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆