【问题标题】:Should I add an "async" to a short method or not? [duplicate]我应该在短方法中添加“异步”吗? [复制]
【发布时间】:2017-04-27 06:21:20
【问题描述】:
async void Main()
{
    var cp=new ConentProxy();
    Console.WriteLine(await cp.GetAsync());
    Console.ReadLine();
}

// Define other methods and classes here
public class HttpsContentProvider : IContentProvider
{
    private static HttpClient hc=new HttpClient();

    //**@No.1**
    public async Task<string> GetAsync() {
        return await hc.GetStringAsync("https://www.stackoverflow.com").ConfigureAwait(false);
    }
}

public class DefaultContentProvider : IContentProvider
{
    //**@No.2**
    public async Task<string> GetAsync()
    {
        return await Task.FromResult("Default").ConfigureAwait(false);
    }
}
public interface IContentProvider
{
    Task<string> GetAsync();
}

public class ConentProxy : IContentProvider
{
    public static int conentType = int.Parse(ConfigurationManager.AppSettings["UseHttps"] ?? "0");

    //**@No.3**
    public async Task<string> GetAsync()
    {
        switch (conentType)
        {
            case 0:return await new HttpsContentProvider().GetAsync();
            default:return await new DefaultContentProvider().GetAsync();
        }
    }
}

在上面的代码中,前面有三个带有“@No.”标签的“async”。它们都是简短的方法,只有一两行。

它们可以在没有“异步”的情况下等待,因为它们返回 TaskTask&lt;T&gt;

实际代码中No.1标签上的调用层可能远不止2个。所以会有很多“异步”级联。

我应该在短方法中添加“异步”吗?据我所知,asyncawait 需要付费;

特别是No.3,它只是一种代理方法。真正的操作方法会阻塞在@No.1处的HttpClient.GetStringAsync

================================================ ======

在阅读@dustinmoris 的第一个答案后,我在HttpClient 类中找到了以下代码。让我困惑的是没有async也没有ConfigureAwait(false),这和HttpClient的其他方法一样

public Task<byte[]> ReadAsByteArrayAsync()
{
    this.CheckDisposed();
    TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
    this.LoadIntoBufferAsync().ContinueWithStandard((Action<Task>) (task =>
    {
        if (HttpUtilities.HandleFaultsAndCancelation<byte[]>(task, tcs))
            return;
        tcs.TrySetResult(this.bufferedContent.ToArray());
    }));
    return tcs.Task;
}

【问题讨论】:

  • 仅当操作需要时间时才使用异步,例如 HTTP 请求。不要通过方法的长度来决定是否使用异步。
  • 我的经验法则是不要开始将任何方法写成async。在我需要插入await 时,我将添加async。但是在你的例子中,你的方法只是return await,我想说你不需要那里的await(如果方法不是async)。

标签: c# .net asynchronous async-await


【解决方案1】:

从技术上讲,有更好的解释,但对于初学者来说,经验法则应该是:

在什么时候使用异步

  1. 一个库为您提供了一个异步选项,然后它通常会从异步中受益匪浅(HttpClient、StreamReader 等)
  2. 如果因为 1. 您必须在某处使用异步,那么您必须一直使用异步,因为调用异步方法的每个更高级别的方法现在本质上也是异步的。
  3. 如果 1. 和 2. 不适用,则不要将方法转为异步,否则

方法的长度与它无关,实际上方法越小越好,因为它是良好编码习惯的标志。

async/await 的额外成本,即使它确实遍布您的代码,通常也超过了您遵循规则 1. 和 2 所获得的收益。

现在回答这个问题,如果您可以直接返回任务,是否必须使用异步装饰方法:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多