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