简体   繁体   English

C# ASP.NET 内核 API 异步/等待 VS 结果

[英]C# ASP.NET Core API Async/await VS Result

I'm a bit confused on best practices with c# and tasks.我对 c# 和任务的最佳实践有点困惑。
When I was taught c# and tasks it was always an async function that awaits a task.当我被教导 c# 和任务时,它始终是等待任务的异步 function。 But recently I have been doing some research and found some people who say otherwise.但最近我一直在做一些研究,发现一些人持不同意见。 They also say that limiting usage of async and await can improve performance and Ram usage.他们还说,限制 async 和 await 的使用可以提高性能和 Ram 使用率。

For example in This Stackoverflow post It says you shouldn't always await every task but the example isnt for an ASP.NET API and there isn't any previous data used to get the new data.例如在这个 Stackoverflow 帖子中它说你不应该总是等待每个任务,但这个例子不是 ASP.NET API 并且没有任何以前的数据用于获取新数据。 This post also is in favor of not always awaiting every task. 这篇文章也赞成不要总是等待每一项任务。 But again the example is a simple task being passed through.但同样,这个例子是一个简单的任务。

So my question is for cases when there is another task on which the second task must wait.所以我的问题是针对第二个任务必须等待的另一个任务的情况。 Can you use .Result or is it better us use async/await.您可以使用.Result还是我们使用 async/await 更好。 Because I heard .Result is blocking the current thread.因为我听说.Result正在阻塞当前线程。 But I can't see how the current thread would not be blocked by the await since the output of the first statement is needed for the second statement.但是我看不到当前线程如何不会被 await 阻塞,因为第二个语句需要第一个语句的 output 。

Example without async/await没有异步/等待的示例

public Task<User> SaveUser(User user) 
{
    var dbUser = _userRepository.GetByUid(user.Id).Result;
    if(dbUser == null) {
        dbUser = new User();
        dbUser.Id = Guid.NewGuid();
    }
    dbUser.Name = user.Name;

    return _userRepository.Save(dbUser);

}

Example with async/await异步/等待的示例

public async Task<User> SaveUser(User user) 
{
    var dbUser = await _userRepository.GetByUid(user.Id);
    if(dbUser == null) {
        dbUser = new User();
        dbUser.Id = Guid.NewGuid();
    }
    dbUser.Name = user.Name;

    return await _userRepository.Save(dbUser);

}

Note: I also heard that when using an UI, it's important that UI related tasks are awaited but this would be for API's.注意:我还听说在使用 UI 时,等待与 UI 相关的任务很重要,但这是针对 API 的。

I recommend reading my async intro and following up with my post oneliding async and await .我建议阅读我的async介绍并跟进我关于eliding asyncawait的帖子。 TL;DR: use async / await by default, and only elide them when the method is a simple passthrough method. TL;DR:默认使用async / await ,只有当方法是简单的 passthrough 方法时才忽略它们。 Since your example is not a simple passthrough method, you should keep the async / await keywords.由于您的示例不是简单的直通方法,因此您应该保留async / await关键字。

It's also important to draw a distinction between "asynchronous" and async .区分“异步”和async也很重要。 There are several kinds of asynchronous code, whereas async is an implementation detail - one specific kind of asynchronous code.有几种异步代码,而async是一个实现细节 - 一种特定类型的异步代码。 Both of the methods in your question are asynchronous, but only one uses async .您问题中的两种方法都是异步的,但只有一种使用async

They also say that limiting usage of async and await can improve performance and Ram usage.他们还说,限制 async 和 await 的使用可以提高性能和 Ram 使用率。

Yes, by removing the state machine overhead of the async keyword.是的,通过删除async关键字的 state 机器开销。 However, this also removes all the benefits of the state machine, so you should only remove async on simple passthrough methods.但是,这也消除了 state 机器的所有优点,因此您应该只删除简单直通方法上的async

Can you use.Result or is it better us use async/await.你可以使用.Result 还是我们使用 async/await 更好。 Because I heard.Result is blocking the current thread.因为我听说.Result 正在阻塞当前线程。

You should use async / await whenever possible, and avoid Result , even on ASP.NET Core .您应该尽可能使用async / await ,并避免Result ,即使在 ASP.NET Core 上也是如此

But I can't see how the current thread would not be blocked by the await since the output of the first statement is needed for the second statement.但是我看不到当前线程如何不会被 await 阻塞,因为第二个语句需要第一个语句的 output 。

The thread is not blocked.线程没有被阻塞。 await works by sticking a bookmark in the method and then returning a result. await通过在方法中粘贴书签然后返回结果来工作。 So the thread is not blocked, but you can think of the method as "paused".所以线程并没有被阻塞,但是你可以把方法想成“暂停”。 https://blog.stephencleary.com/2012/02/async-and-await.html https://blog.stephencleary.com/2012/02/async-and-await.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM