asp.net 如何使用C#高效地执行100多个API

n6lpvg4x  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(161)

我使用C#与ASP NET Web Api解决方案(.net7.0)的想法是,我可以接受超过100个POST请求,可能高达1000个请求,执行一个API,每个请求将打开一个数据库连接-但是数据库设置为允许无限连接。所以我不认为这是个问题
这些是我到目前为止经历的考验:
似乎没有一个能正常工作。

var syntaxCommands = GetCommands();

//Test One
//ERROR - Timeout error
var tasks = new List<Task<object>>();
foreach (var cmd in syntaxCommands)
{
    tasks.Add(_syntaxExecutor.Execute(cmd));
}
var testResult = await Task.WhenAll(tasks);

//Test Two
//Takes way too long
foreach (var command in syntaxCommands)
{
    await Task.Run(() => _syntaxExecutor.Execute(command));
}

//Test Three
Parallel.ForEach(syntaxCommands, async e =>
{
    await Task.Run(() => _syntaxExecutor.Execute(e));
});

字符串
执行API的代码:

public async Task<object> Execute(SyntaxCommand command)
    {
        var json = GetJson(command);
        using (var client = new HttpClient())
        {
            client.Timeout = TimeSpan.FromMinutes(10);
            HttpContent content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            try
            {
                var response = await client.PostAsync("https://localhost:44346/SyntaxExecutor", content);
                var responseBody = await response.Content.ReadAsStringAsync();
                return responseBody;
            }
            catch (Exception ex) 
            {
                File.AppendAllText(@"D:\API-LOAD-Tests\logs-api.txt", ex.Message);
            }

        }
        return null;
    }

    private string GetJson(SyntaxCommand command)
    {
        var updatedSyntax = command.Syntax.Replace(@"""", @"\""");
        var json = @$"""syntax"": ""{updatedSyntax}"", ""replacementVariableId"": {command.VariableId}, ""hierarchyId"": {command.HierarchyId}";
        json = json.Insert(0, "{");
        json = json.Insert(json.Length, "}");
        return json;
    }

ippsafx7

ippsafx71#

Parallel.ForEach不支持Task,所以它只使用并行化来启动任务,但它们都将并行运行,通常你不想用不受限制的并发请求数来访问数据库。您可以使用Parallel.ForEachAsync-沿着以下代码:

await Parallel.ForEachAsync(syntaxCommands, async (cmd, ct) => await _syntaxExecutor.Execute(cmd));

字符串
然后使用它的设置,以便根据经验找到要通过的最佳并行化设置(这取决于您的设置-数据库和实际查询):

await Parallel.ForEachAsync(
    syntaxCommands, 
    new ParallelOptions
    {
        MaxDegreeOfParallelism = 8 // here
    },
    async (cmd, ct) => ...);

相关问题