异步等待在哪里结束?困惑 [英] Where does async and await end? Confusion

查看:44
本文介绍了异步等待在哪里结束?困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个无用的程序,只能帮助我了解异步和等待的工作方式.它是一个控制台应用程序,它解析XML并等待返回名称(姓或名).这是代码:

I have a program which has no purpose but to help me understand how async and await works. It's a console application which parses XML and waits for a name to be returned, either the surname or the first name. Here is the code:

static void Main(string[] args)
{
     Task<string> name = GetFirstParsedName();
     name.Wait();
     if (name.IsCompleted)
     {
         Console.WriteLine(name.Result);
     }

     Console.ReadLine();
 }

static async Task<string> GetFirstParsedName()
{
  string xmlSnippet = @"<person>
<FirstName>Chamir</FirstName>
<Surname>Bodasing</Surname>
<Gender>Male</Gender>
<Nationality>South African</Nationality></person>";

  XmlDocument xmlDoc = new XmlDocument();
  xmlDoc.LoadXml(xmlSnippet);

  XmlParser xmlParser = new XmlParser();
  Task<string> t_GetFirstName = xmlParser.GetFirstName(xmlDoc);
  Task<string> t_GetSurname = xmlParser.GetSurname(xmlDoc);  

  Task<string> t_firstReturnedName = await Task.WhenAny(new Task<string>[] { t_GetFirstName, t_GetSurname });

  string firstReturnedName = await t_firstReturnedName;
  return firstReturnedName;    
}

static async Task<string> GetFirstName(XmlDocument personXml)
{
  string firstName = personXml.SelectSingleNode("//FirstName").InnerText;
  await Task.Delay(5000);
  return firstName;
}

static async Task<string> GetSurname(XmlDocument personXml)
{
  string surname = personXml.SelectSingleNode("//Surname").InnerText;
  await Task.Delay(1);
  return surname;
}

当您不必将值返回给main方法时,似乎只有使用async方法才有意义.除非这意味着设置可以访问的全局类属性.如果不是,则为了等待该方法,所有方法都必须是异步的,这又意味着返回类型必须为 Task< T> .除非我明确必须编写以下代码(就像上面的main方法一样),否则它似乎永远不会结束:

It seems like it only makes sense to use the async method when you don't have to return a value to a main method. Unless it means setting a global class property which can then be accessed. If not, in order to await the method, all methods need to be async which in turn means that the return type must be Task<T>. It seems like it never ends unless I explicitly have to write the following code (as in above main method):

Task<string> name = GetFirstParsedName();
name.Wait();
if (name.IsCompleted)
{
    Console.WriteLine(name.Result);
 }

我的理解完全正确吗?我必须使用result属性来获取此处的值,并通过阅读该内容来获得该值,这似乎不是最佳实践.

Is my understanding correct at all? I have to use the result property to get the value here and from reading up about this, it seems that this is not the best practice.

推荐答案

当您不必将值返回给main方法时,似乎只有使用async方法才有意义.

It seems like it only makes sense to use the async method when you don't have to return a value to a main method.

为什么这么说?无论您何时正在进行自然的异步操作,都应使用异步方法.无论该操作是否具有返回值.

Why do you say that? It makes sense to use an async method where-ever you have a naturally asynchronous operation ongoing. No matter if that operation has a return value or doesn't.

为了等待该方法,所有方法都必须是异步的,这又意味着返回类型必须为"Task".似乎永无止境

in order to await the method, all methods need to be async which in turn means that the return type must be "Task" . It seems like it never ends

是正确的.异步在底部到堆栈顶部.它通常到达堆栈中的最高调用位置(可以是控制台 Main 方法或UI事件处理程序).那是使用 async 的优点,它允许您在释放调用线程的同时异步等待操作.例如,如果您有一个WebAPI端点需要同时处理大量请求,那么这将有所帮助.如果您将大部分时间都花在查询数据库上,则可以同时释放该调用线程来处理更多请求.

That's correct. Async spreads in your code like a plage, from the bottom to the top of your stack. It usually reaches the highest calling place in your stack (be it a console Main method or a UI event handler). That's the advantage of using async, it allows you to asynchronously wait an operation while freeing the calling thread. This can help, for example, if you have a WebAPI endpoint which needs to handle a large amount of requests concurrently. If you spend most of your time querying a database, you can free that calling thread in the meanwhile to serve more requests.

我的理解完全正确吗?我必须使用result属性来获取此处的值,并通过阅读该内容来获得该值,这似乎不是最佳实践.

Is my understanding correct at all? I have to use the result property to get the value here and from reading up about this, it seems that this is not the best practice.

您必须使用 Result 属性,因为控制台应用程序是一种特殊情况,其中 Main 不能标记为 async (除非您正在使用ASP.NET CoreCLR控制台应用程序).如果这是UI事件处理程序或ASP.NET操作,则可以正确地 await 异步调用.

You have to use the Result property because a console application is a special case, where Main cant be marked as async (unless you're using ASP.NET CoreCLR console app). If this was a UI event handler or an ASP.NET action, you'd properly await the async call.

这篇关于异步等待在哪里结束?困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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