簡體   English   中英

如何在並行線程中獲取當前 object

[英]How get current object in operation parallel Thread

我是發送到 api 的 Object 列表。我在下面使用了並行線程。
代碼

  List<object> data  ;//contain data

                result =new  Dictionary<decimal, object>();
                

                var threadCount = 4;
                if (data.Count < threadCount)
                {
                    threadCount = data.Count;
                }

                var pageSize = threadCount > 0 ? Convert.ToInt32(Math.Ceiling((Convert.ToDecimal(data.Count) / threadCount))) : 0;
                var pageCount = threadCount;

                

                for (int j = 0; j < threadCount; j++)
                {

                    var temp = data.Skip(j * pageSize).Take(pageSize).ToList();
                    var tempLength = temp?.Count;
                    Parallel.ForEach(temp, item =>
                    {
                        result.Add(item.ID, null);

                       //call Api and get resultApi

                        if (resultApi != null && resultApi.Result != null)
                        {
                            
                            result[item.ID] = resultApi.Result.id;
                        }
                        else if (resultApi != null && resultApi .Message != null)
                        {
                            
                            result[item.ID] = null;
                        }
                        else
                        {
                            result[item.ID] = null;
                        }
                    });
                 }

問題
在檢查結果的頂部操作中,我看到一些項目與其 ID 無關並且已被移動。如果退出並行模式時沒有移位,則所有標識符都已正確設置如何解決問題?

我的建議是使用PLINQ而不是Parallel class。 對於入門級多線程,它是一種更安全的工具。 PLINQ 類似於 LINQ,但它以.AsParallel()開頭。 它包括幾乎所有熟悉的 LINQ 運算符,如SelectWhereTakeToList等。

Dictionary<decimal, object> dictionary = data
    .AsParallel()
    .WithDegreeOfParallelism(4)
    .Cast<Item>()
    .Select(item => (item.ID, CallAPI(item).Result))
    .Where(entry => entry.Result != null)
    .ToDictionary(entry => entry.ID, entry => (object)entry.Result.Message);

假定CallAPI方法具有以下簽名: Task<APIResult> CallAPI(Item item);

此 PLINQ 查詢將以 4 的並發級別處理您的數據。這意味着 4 個操作將同時進行,當一項完成時,下一項將自動開始。

ID應該是唯一的,否則ToDictionary運算符將拋出異常。

建議使用這種方法是因為它的簡單性,而不是它的效率。 PLINQ 並不是真正用於處理 I/O 綁定的工作負載,並且在這樣做時會不必要地阻塞ThreadPool線程。 您可以在此處查找更有效的方法來限制異步 I/O 綁定操作。

我已經找到答案了。 如下。
代碼

List<object> data  ;//contain data

                result =new  Dictionary<decimal, object>();
                

                var threadCount = 4;
                if (data.Count < threadCount)
                {
                    threadCount = data.Count;
                }

                var pageSize = threadCount > 0 ? Convert.ToInt32(Math.Ceiling((Convert.ToDecimal(data.Count) / threadCount))) : 0;
                var pageCount = threadCount;

                

                for (int j = 0; j < threadCount; j++)
                {

                    var temp = data.Skip(j * pageSize).Take(pageSize).ToList();
                    var tempLength = temp?.Count;
                    Parallel.ForEach(temp, item =>
                    {
                      lock (result)
                        {
                           var temp = callapi(item.ID);
                           result.Add(temp.Item1, temp.Item2);
                        }
                    });
                 }
     private (decimal, object) callapi(decimal id){
                        //call Api and get resultApi

                        if (resultApi != null && resultApi.Result != null)
                        {
                            
                            result[item.ID] = resultApi.Result.id;
                            return (id,result);
                        }
                        else if (resultApi != null && resultApi .Message != null)
                        {
                            
                            result[item.ID] = null;
                            return (id,result);
                        }
                        else
                        {
                            result[item.ID] = null;
                            return (id,result);
                        }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM