首页 > 解决方案 > 并行for循环的问题

问题描述

我正在尝试通过从 api 调用异步加载每个页面并将所有相同的项目放在字典中的列表中来加载完整的拍卖行。当我进行并行 for 循环时,它不会返回任何内容。帮助将被appricieted。

祝你有美好的一天!-Vexea

    {
        string url = "https://api.hypixel.net/skyblock/auctions";

        //Gets number of pages to make threads on the auction house...
        using (HttpResponseMessage response = await ApiHelper.GetApiClient("application/json").GetAsync(url))
        {
            if (response.IsSuccessStatusCode)
            {
                AuctionHouseModel auctionHouse = await response.Content.ReadAsAsync<AuctionHouseModel>();
                return auctionHouse.Pages;
            }
            else
            {
                return 0;
            }
        }
    }

    private static async Task<AuctionPageModel> LoadHypixelAuctionPage(int page, string apiKey)
    {
        //Loads a solid page...
        string url = "https://api.hypixel.net/skyblock/auctions?key=" + apiKey + "&page=" + page;

        using (HttpResponseMessage response = await ApiHelper.GetApiClient("application/json").GetAsync(url))
        {
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsAsync<AuctionPageModel>();
            }
            else
            {
                return null;
            }
        }
    }

    public async static Task<AuctionHouseModel> LoadHypixelAuctionHouse(string apiKey)
    {
        //Loads all pages needed and puts them into a dictionary...
        List<AuctionPageModel> pages = new List<AuctionPageModel>();
        AuctionHouseModel output = new AuctionHouseModel();

        Parallel.For(1, await LoadHypixelAuctionPages(), async page => {
            pages.Add(await LoadHypixelAuctionPage(page, apiKey)); //This returns nothing, count of pages stays 0 and nothing happens...
        });

        foreach (AuctionPageModel page in pages)
            foreach(AuctionProductModel product in page.Products)
                try
                {
                    output.Products[product.Name].Add(product);
                }
                catch
                {
                    output.Products.Add(product.Name, new List<AuctionProductModel>());
                    output.Products[product.Name].Add(product);
                }
        output.Pages = await LoadHypixelAuctionPages();
        return output;
    }

标签: c#asynchronous

解决方案


您不能将任何Parallel方法与async. Parallel 用于 CPU 绑定代码,并且async(主要)用于 I/O 绑定代码。Parallel班级没有正确理解任何async事情。

您需要异步并发(Task.WhenAll),而不是并行并发:

List<AuctionPageModel> pages = new List<AuctionPageModel>();
AuctionHouseModel output = new AuctionHouseModel();

var tasks = Enumerable
    .Range(1, await LoadHypixelAuctionPages())
    .Select(async page => pages.Add(await LoadHypixelAuctionPage(page, apiKey)))
    .ToList();
await Task.WhenAll(tasks);

或者,更简单地说:

AuctionHouseModel output = new AuctionHouseModel();

var tasks = Enumerable
    .Range(1, await LoadHypixelAuctionPages())
    .Select(async page => await LoadHypixelAuctionPage(page, apiKey))
    .ToList();
var pages = await Task.WhenAll(tasks);

推荐阅读