c# - 如何在 ASP.NET 中使用 Task 处理多个请求批处理?

标签 c# asp.net multithreading task-parallel-library async-await

我有一个选定的 contentId 列表,对于每个内容 ID,我需要调用一个 API,获取响应,然后将接收到的每个内容的响应保存在数据库中。

用户一次可以选择 1 到 1000 之间的任意数量的内容,并可以在从 api 获得响应后传递它以更新内容数据库详细信息。

在这种情况下,我最终为每个内容创建了多个请求。

我想继续asp.net async Task操作,然后写了下面这个方法。

我编写的代码目前为每个 contentId 创建一个任务,最后我正在等待所有任务以获取响应。

Task.WaitAll(allTasks);

public static Task<KeyValuePair<int, string>> GetXXXApiResponse(string url, int contentId)
{
    var client = new HttpClient();

    return client.GetAsync(url).ContinueWith(task =>
    {
        var response = task.Result;
        var strTask = response.Content.ReadAsStringAsync();
        strTask.Wait();
        var strResponse = strTask.Result;

        return new KeyValuePair<int, string>(contentId, strResponse);
    });
}

我现在正在考虑为我创建的每个任务创建一个线程,反过来,由于工作线程数量有限,这种方法最终会占用所有线程,这是我不希望发生的。

任何人都可以帮助/指导我如何有效地处理这种情况,即处理多个 api 请求或使用异步任务等进行批处理吗?

仅供引用:我正在使用 .NET Framework 4.5

最佳答案

任务只是可以等待和取消的异步操作的表示。创建新任务不一定会创建新线程(大多数情况下不会)。如果您正确使用 async-await,在大多数异步操作期间甚至不会有线程。

但是,同时发出许多请求仍然存在问题(例如,内容服务器负担过重)。因此,您可能仍想使用 SemaphoreSlimTPL Dataflow 来限制并发调用的数量:

private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(100);

public static async Task<KeyValuePair<int, string>> GetXXXApiResponse(string url, int contentId)
{
    await _semaphore.WaitAsync();
    try
    {
        var client = new HttpClient();
        var response = await client.GetAsync(url);
        var strResponse = await response.Content.ReadAsStringAsync();
        return new KeyValuePair<int, string>(contentId, strResponse);
    }
    finally
    {
        _semaphore.Release();
    }
}

要等待这些任务完成,您应该使用 Task.WhenAll 来异步等待,而不是使用 Task.WaitAll 来阻塞调用线程:

await Task.WhenAll(apiResponses);

关于c# - 如何在 ASP.NET 中使用 Task 处理多个请求批处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25288642/

相关文章:

c# 内存游戏,需要在游戏结束时添加消息

c# - 当对象超出范围时,事件处理程序会发生什么?

C# HttpClient : Why MediaTypeWithQualityHeaderValue?

c++ - 循环缓冲区的线程安全实现

c# - 使用 C# 的 Atom 条目

asp.net - 将 JSON 数据传递到 Web 服务

c# - ASP.NET TextBox 忽略更新面板

c# - TPL 任务的 ThreadStatic

c++ - 如何等待此线程池中的所有任务完成?

c# - 消息队列和服务总线的消息粒度