【问题标题】:async call not effectiveness in asp.net core异步调用在 asp.net 核心中无效
【发布时间】:2017-10-10 08:00:44
【问题描述】:

我想在 ASP.NET Core 2.0 中测试异步请求与同步请求的有效性。为此,我将 Kestrel/Libuv ThreadCount 设置为 1 以强制它对所有请求仅使用单个线程。

public class Program
{
    public static void Main(string[] args)
    {
        WebHost.CreateDefaultBuilder(args)
            .UseLibuv(options =>
            {
                options.ThreadCount = 1;
            })
            .UseStartup<Startup>()
            .Build()
            .Run();
    }
}

然后我在控制器中编写了一些简单的代码来调用异步方法。在 index 动作中,我在 ViewBag 中设置了开始时间,然后异步调用了Doing 函数,最后在 ViewBag 中设置了结束时间。

public class HomeController : Controller
{
    public async Task<IActionResult> Index()
    {
        ViewBag.Start = DateTime.Now;
        await Doing();
        ViewBag.Finish = DateTime.Now;

        return View();
    }

    public async Task Doing()
    {
        await Task.Delay(5000);
    }
}

查看代码是:

<div class="row">
    Start: @ViewBag.Start
</div>
<div class="row">
    Finish: @ViewBag.Finish
</div>

当我运行应用程序并同时在两个浏览器中浏览页面时,我预计请求的开始时间会大致相等。但是在尝试这样做时,第二个请求仅在第一个请求完成后才开始。

两个浏览器的输出例如是这样的:

Start: 10/10/2017 10:16:36 AM
Finish: 10/10/2017 10:16:43 AM

Start: 10/10/2017 10:16:43 AM
Finish: 10/10/2017 10:16:50 AM

我的测试或概念有什么问题?

【问题讨论】:

  • 在 ASP.NET Core 2 中,线程数是使用 .UseLibuv(….) 而不是 .UseKestrel(…) 配置的
  • @poke,谢谢,但你的意见是什么?
  • 我还没有答案。顺便提一句。除了那些网络调用,您还可以简单地执行 await Task.Delay(5000) 等待 5 秒,以实现不依赖网络的一致测试。
  • 仅供参考,这里也发布了:github.com/aspnet/Mvc/issues/6937
  • @Eilon,我将此问题添加到 github

标签: c# asynchronous asp.net-core


【解决方案1】:

为了对此进行测试,我将以下代码添加到Program Main 方法中,工作线程数设置为4。

public static void Main(string[] args)
{
    ThreadPool.SetMaxThreads(workerThreads: 4, completionPortThreads: 4);

    CreateWebHostBuilder(args).Build().Run();
}

并在控制器中添加两种简单的查询方法,一种是简单的,一种是异步的。两个查询都需要 2 秒才能执行。我使用Dapper 进行运行查询。

private void Query()
{
    using (SqlConnection connection = new SqlConnection(_connectionString))
    {
        connection.Execute("WAITFOR DELAY '00:00:02';");
    }
}

private async Task QueryAsync()
{
    using (SqlConnection connection = new SqlConnection(_connectionString))
    {
        await connection.ExecuteAsync("WAITFOR DELAY '00:00:02';");
    }
}

然后我为同步、异步、并行测试添加三个操作

public IActionResult Sync()
{
    Query();
    Query();

    return Ok();
}

public async Task<IActionResult> Async()
{
    await QueryAsync();
    await QueryAsync();

    return Ok();
}

public async Task<IActionResult> Parallel()
{
    var task1 = QueryAsync();
    var task2 = QueryAsync();

    await task1;
    await task2;

    return Ok();
}

我通过West Wind WebSurge Load Tester 使用以下配置测试我的场景

执行时间:60 秒,发送请求的线程数:10

这张图片是我的测试结果,显示了成功请求的数量、失败的请求数量以及每个操作的平均请求时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2020-10-12
    • 2020-01-18
    • 2019-11-20
    • 2020-01-06
    • 1970-01-01
    相关资源
    最近更新 更多