我有一个程序,它没有任何用途,只是为了帮助我理解 async 和 await 的工作原理。它是一个控制台应用程序,它解析 XML 并等待返回姓名,可以是姓氏或名字。这是代码:
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>
.除非我明确必须编写以下代码(如上面的主要方法),否则它似乎永远不会结束:
Task<string> name = GetFirstParsedName();
name.Wait();
if (name.IsCompleted)
{
Console.WriteLine(name.Result);
}
我的理解完全正确吗?我必须使用 result 属性来获取此处的值,并且阅读相关内容后发现,这似乎不是最佳做法。
最佳答案
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.
你的 async
方法可以返回 Task<T>
返回一个值给它的调用者。如果异步方法依赖于副作用(即设置属性/全局变量),它们就不能很好地工作;如果您的代码更纯净(即获取参数并返回结果),它们会工作得更好。
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" . It seems like it never ends
这就是为什么 async
的中心原则之一是“一路异步”。在大多数应用程序中,这正是您应该做的。最终,“异步链”通常以 async void
结束。事件处理程序(用于 UI 应用程序)或 async Task<T>
入口点(对于 ASP.NET 应用程序)。控制台应用程序不常见,因为它们确实需要明确的 Wait()
/Result
或在其 Main
中的等效的方法。
毕竟整点async
是释放调用线程。如果调用堆栈中的下一个方法阻塞同一个线程,直到 async
代码是完整的,好吧,那是毫无意义的大量工作......
关于c# - async 和 await 在哪里结束?困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067874/