如何以更好的性能执行多个异步操作

时间:2019-04-01 14:00:23

标签: c# asp.net-core .net-core

我想进行多个异步调用并将结果提取到一个列表中,但是我不确定我是否将其制作成最佳方法。

我尝试将使用System.Net.Http.HttpClient进行的所有调用添加到列表中,并在函数末尾使用lambda提取结果。我知道它应该可以打几个电话,但是增加电话数量会大大降低性能。

public async Task<string> LoopMulticurrencyGetTime (int loop)
{
    List<Task<HttpResponseMessage>> responses = new List<Task<HttpResponseMessage>>();

    for (int i = 0; i < loop; i++)
        responses.Add(ExampleClient.GetAsync("Time"));

    await Task.WhenAll(responses);

    return JsonConvert.SerializeObject(responses.Select(r =>
        r.Result.Content.ReadAsStringAsync().Result));
}

我想做类似的事情:

public async Task<string> LoopMulticurrencyGetTime (int loop)
{

    List<Task<String>> responses = new List<Task<String>>();
    List<String> s = new List<string>();

    for (int i = 0; i < loop; i++)
        //responses.Add(ExampleClient.GetAsync("Time"));
        responses.Add(ExampleClient.GetStringAsync("Time"));

    return JsonConvert.SerializeObject(responses.Select(s => s.Result));
}

但是它似乎并没有真正异步运行,看起来也不是很平滑。

您对如何提高代码性能有任何建议吗?

编辑:

这是ExampleController→

[Route("/Example")]
[ApiController]
public class ExampleController : Controller
{
    ExampleService exampleService = new ExampleService();

    [HttpGet]
    [Route("Time")]
    public string getTime()
    {
        try
        {
            return DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); ;
        }
        catch (Exception e)
        {
            return null;
        }
    }

    [HttpPost]
    [Route("Loop/{loop}")]
    public async Task<String> loopTest(Int32 loop)
    {
        try
        {
            return await exampleService.LoopGetTime(loop);
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }

    [HttpPost]
    [Route("Benchmark/{loop}")]
    public async Task<String> becnhmark(Int32 loop)
    {
        try
        {
            return await exampleService.Benchmark(loop);
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您的问题在这里确实不清楚。通常,您的第一种方法很好。但是,就像其他人所说的那样,循环值上应该有一些界限。

除了省略了上一个方法的Task.WhenAll调用这一事实之外,还不清楚第二个“所需”方法的错误之处。如果添加它,那么此表格也可以正常工作。

首先,您需要认识到异步与性能无关;这与规模有关。如果除其他原因外,异步代码仅会引起一些开销,那么异步代码通常会 性能差。这可能只需要几毫秒的时间,但按通话,异步代码的平均速度将比同步慢。

异步购买给您的是规模。与异步处理相比,与异步处理相比,您可以处理更多的请求,并且通常可以更好地利用资源。就是这样。

现在就为什么您通常找不到这种表现出色的人而言,可能有多种原因。首先,您没有指定操作方式。例如,如果您正在Visual Studio中进行测试,则说明您正在处理单线程Web服务器(IIS Express),因此即使使用异步,请求仍将按顺序处理。在另一种设置上,您可能只是在耗尽可用资源。异步不是免费的。仍然有很多事情在发生,如果没有足够的RAM或CPU,网络延迟过长等等,所有这些仍然可能导致性能下降。

通常,异步不是魔术棒。您仍然受到硬约束的束缚。异步只是比同步更好地利用了可用资源,但是仍然受到上述资源的限制。