C# 如何在需要大量时间的循环中处理多线程方法?

C# 如何在需要大量时间的循环中处理多线程方法?,c#,multithreading,json.net,C#,Multithreading,Json.net,我正在编写一些代码,其目标是连接到API以获取用户名 目前,我让代码在一个循环中工作,由此产生了运行时问题。每个“用户名列表”可能有数千个,这可能需要数小时才能获得所有用户名。我的目标是找出如何使其线程化,以允许同时进行多个查找 以下是我的代码,以及理解代码所需的重要信息: using Newtonsoft.Json.Linq; public List<LeaderboardItem> LeaderboardList; public LeaderboardItem LBItem;

我正在编写一些代码,其目标是连接到API以获取用户名

目前,我让代码在一个循环中工作,由此产生了运行时问题。每个“用户名列表”可能有数千个,这可能需要数小时才能获得所有用户名。我的目标是找出如何使其线程化,以允许同时进行多个查找

以下是我的代码,以及理解代码所需的重要信息:

using Newtonsoft.Json.Linq;

public List<LeaderboardItem> LeaderboardList;
public LeaderboardItem LBItem;
public GetNames getNames;

public GetLeaderboardRuns(string GameCode, string Category, string Query)
{
    LeaderboardList = new List<LeaderboardItem>();

    var Client = new WebClient();

    try
    {
        var Data = Client.DownloadString($"{URL.BaseUrl}/leaderboards/{GameCode}/category/{Category}{Query}");

        foreach (var item in (JArray)JObject.Parse(Data)["data"]["runs"])
        {
            int place = (int)item["place"];

            // This next line looks up the username on the API.
            // This code takes several seconds per loop to complete.
            // It is returned as a list of strings.
            getNames = new GetNames(item["run"]["players"]); 

            double time = (double)item["run"]["times"]["primary_t"];

            LBItem = new LeaderboardItem
            {
                Rank = place,
                Name = getNames.names,
                Time = time
            };

            LeaderboardList.Add(LBItem);
        }
    }
    catch (Exception err)
    {
        MessageBox.Show($"Error: {err.Message}", "Error!");
    }
}
我的预期结果应该是,在开始下一个用户名查找之前,它不依赖于每个循环是否完成。但是,我在这种方式的多线程处理方面缺乏经验,因此非常感谢您的帮助


多谢各位

您可以在
Parallel
class:
Parallel.For
静态方法中使用wonderfull方法。它将并行运行循环的每个迭代,从而加快程序的速度

为了使用该方法,您需要稍微重构代码,以便它可以并行运行:最好避免在线程之间共享数据,如果您使用
并行,您可以通过线程共享一些变量。对于
,这些变量是
getNames
LBItem

LeaderboardList.Add(new LeaderboardItem
{
    Rank = place,
    Name = (new GetNames(item["run"]["players"])).names,
    Time = time
};

您可以使用上述方法,而不是单独创建对象并将其分配给共享变量。

您可以在
Parallel
class:
Parallel.For
静态方法中使用wonderfull方法。它将并行运行循环的每个迭代,从而加快程序的速度

为了使用该方法,您需要稍微重构代码,以便它可以并行运行:最好避免在线程之间共享数据,如果您使用
并行,您可以通过线程共享一些变量。对于
,这些变量是
getNames
LBItem

LeaderboardList.Add(new LeaderboardItem
{
    Rank = place,
    Name = (new GetNames(item["run"]["players"])).names,
    Time = time
};

您可以使用上面的方法,而不是单独创建对象并将它们分配给共享变量。

我在循环中使用
getNames.names
,然后将
LBItem
对象添加到公共列表
排行榜列表中。循环的工作原理与它应该的完全相同。编辑:我将循环到
Parallel。谢谢你的建议@SirRufo Ok,现在应该可以了:)@MichałTurczyn,这取决于并行的
实现。For
需要
排行榜列表
成为线程安全的集合,因此OP必须将
列表
更改为
ConcurrentBag
我在循环中使用
getNames.names
,然后将
LBItem
对象添加到公共列表
排行榜列表
。循环的工作原理与它应该的完全相同。编辑:我将循环到
Parallel。谢谢你的建议@SirRufo Ok,现在应该可以了:)@MichałTurczyn,这取决于并行的
实现。For
需要
排行榜列表
成为线程安全的集合,因此OP必须将
列表
更改为
ConcurrentBag
否,客户端线程从来不会使需要数小时才能生成几千个用户名的web api更高效。顺便说一句,“小时”非常长,你需要更深入地了解为什么需要这么长的时间。请联系网站所有者以获得支持。此外,还需要一个“顶级”查询,这样您就不必检索所有内容,一个领导委员会没有数千个条目。这里有一个这样的领导委员会:不幸的是,他们的API上没有允许非客户端工作的内容。每个API用户ID搜索大约需要4秒钟。1000个用户>80分钟不,客户端线程从来不会使需要数小时才能生成几千个用户名的web api更高效。顺便说一句,“小时”非常长,你需要更深入地了解为什么需要这么长的时间。请联系网站所有者以获得支持。此外,还需要一个“顶级”查询,这样您就不必检索所有内容,一个领导委员会没有数千个条目。这里有一个这样的领导委员会:不幸的是,他们的API上没有允许非客户端工作的内容。每个API用户ID搜索大约需要4秒钟。1000个用户>80分钟