Web Api 2 OWIN Selfhost处理多个并发请求

时间:2017-05-16 13:50:35

标签: c# asp.net-web-api asp.net-web-api2 owin owin-middleware

我有一个使用OWIN的自主式web api,我似乎在并发连接上挣扎。当我使用50个并发get事件运行压力测试时,响应时间增加很多,即使操作非常简单,返回200 OK,并在uri中键入id。

我的web api OWIN和api控制器如何根据请求同时运行?

这是我项目的一个示例:

启动课程

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        try
        {
            appBuilder.UseWelcomePage("/welcome.html");
            appBuilder.UseErrorPage(new ErrorPageOptions
            {
                ShowExceptionDetails =
    #if DEBUG
                true
    #else
                false
    #endif
            });

            Debug.WriteLine($"Setting Web Api Configuration up...");
            var apiConfig = ConfigureWebApi();
            appBuilder.UseWebApi(new HttpServer(apiConfig));
            appBuilder.UseCors(CorsOptions.AllowAll);

            Debug.WriteLine($"Completed Web Api configuration.");
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"Failed to complete Web Api setup.", ex);
            throw;
        }
    }
}

控制器

public class TestController : ApiController
{
    public async Task<IHttpActionResult> Get(int id)
    {
        return Task<IHttpActionResult>.Factory.StartNew(() => {
            try
            {
                return Ok(id);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message, nameof(Get));
                return InternalServerError();
            }
        });
    }
}

我的web api控制台启动:

public static void Open()
{
    _webApp = WebApp.Start<Startup>(HostAddress);
    Console.WriteLine($"Host open -> {HostAddress}");
}

1 个答案:

答案 0 :(得分:1)

所有api控制器方法都将同时运行,显然受托管api的服务器功能的限制。这是Web服务器的功能,无论是IIS还是自托管。但是,你可以采取一些措施来帮助实现这一目标。

如果你保持一切异步,你会看到最好的表现。例如,如果您的控制器方法如下所示:

public async Task<IHttpActionResult> Get(int id)
{
    var testObject = await _repository.GetAsync(id);

    return Ok(testObject);
}

你有一个如下所示的存储库方法:

public async Task<TestObject> GetAsync(int id)
{
    using(var connection = new SqlConnection(_connectionString)
    {
        // using Dapper
        return await connection.QuerySingleAsync<TestObject>("sp_GetTestObject", new {Id = id}, commandType = CommandType.StoredProcedure);
    }
}

执行此操作允许计算机将工作线程用于数据库I / O,从而释放处理其他任务的处理能力,例如接受对API端点的其他请求。像@StephenCleary这样的人可能会阐述我说的和/或纠正它。 @ StephenCleary&#39; blog和本书绝对值得一读,以了解异步编程。

希望有所帮助。