c# - 如何对列表中的所有元素运行方法 c# 以缩短加载时间

标签 c# .net rest asynchronous

我有一个工作项目需要通过 REST API 为 300 多个用户获取数据,并且在获取所有这些数据之前用户无法继续正确使用该应用程序。理想情况下,我想同时对列表中的每个元素运行 FetchUserDetails 方法,并在详细信息返回时更新每个条目。

注意:为防止阻塞 UI 线程,此功能嵌套在后台工作程序中。

我的用户类看起来像:

public class User 
{
    public List<string> Details { get; set; }
}

在后台 worker 中,我有以下功能:

List<User> users; // List of 300+ users
Parallel.ForEach(users, user =>
{
    user.Details = FetchUserDetails(user);
});

还有 FetchUserDetails 方法,由于 NDA 限制,这里不详细介绍:

private List<string> FetchUserDetails(User inputUser)
{
    // Long running, nested API calls that take over 50 seconds
    return List<string>;
}

有没有办法让我同时对 300 多个条目中的每一个运行该方法,以大大减少获取数据所需的时间。

最佳答案

Parallel.ForEach 允许您设置 MaxDegreeOfParallelism

Parallel.ForEach(
    users, 
    new ParallelOptions { MaxDegreeOfParallelism = 300 },
    user => { user.Details = FetchUserDetails(user); }
);

你甚至可以为 MaxDegreeOfParallelism 做 -1 来表示无限

然而,设置它实际上只会减少它将使用的数量。参见 this doc了解详情。

By default, For and ForEach will utilize however many threads the underlying scheduler provides, so changing MaxDegreeOfParallelism from the default only limits how many concurrent tasks will be used.

正如其他人指出的那样,实际使用的线程数可能受限于您机器的内核数。

更好的方法是使调用异步,这样一旦等待响应的请求被阻塞,原始线程就可以自由启动下一个请求。

类似于:

async Task SetUserDetails(User user)
{
    user.Details = await FetchUserDetails(user);
}

async Task UpdateUsers(IEnumerable<User> users)
{
    var tasks = new List<Task>();
    foreach(var user in users)
    {
         tasks.Add(SetUserDetails(user));
    }
    await Task.WhenAll(tasks);
}

关于c# - 如何对列表中的所有元素运行方法 c# 以缩短加载时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55110261/

相关文章:

c# - 方法定义参数中的赋值运算符 (=)

c# - 如何创建 3D 散点图?

c# - 仅使用 XAML 来防止在 TextBox 中输入字符

C#.NET : How to design a template and multiply it in a form

c# - 如何使用 .NET 2.0 安全地托管插件

cordova - 通过 REST-API 进行 Couchbase 移动复制

django - 测试 REST 访问是否必要/好?

c# - 关于Unity中的OnRenderImage函数

c# - 有人可以解释幕后发生的事情吗?

c# - 在 WCF RESTful 服务中访问请求主体