你怎么能在循环中多线程方法花费很多时间?

Tim*_*uin 0 c# multithreading json.net

我正在研究一些代码,其目标是连接到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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

每个LeaderboardItem看起来如下:

public class LeaderboardItem
{
    public int Rank { get; set; }
    public List<string> Name { get; set; }
    public double Time { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的预期结果应该是在开始下一个用户名查找之前,它不依赖于每个循环来完成.但是,我对这种方式的多线程缺乏经验,所以任何帮助都会非常感激.

非常感谢你!

Mic*_*zyn 5

你可以在Parallelclass中使用wonderfull方法:Parallel.Forstatic method.它将并行运行循环的每个迭代,从而加速您的程序.

在这里阅读更多

为了使用该方法,您需要稍微重构一下代码,因此它可以并行运行:最好避免在线程之间共享数据,如果使用Parallel.For,则在线程上共享一些变量,这些变量是getNamesLBItem:

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

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

  • @MichałTurczyn取决于实现`Parallel.For`将要求`LeaderboardList`成为一个线程安全的集合,因此OP必须将`List <T>`更改为`ConcurrentBag <T>` (2认同)