简体   繁体   English

如何在并行线程中获取当前 object

[英]How get current object in operation parallel Thread

I am List of Object for send to api.i used parallel thread below.我是发送到 api 的 Object 列表。我在下面使用了并行线程。
code代码

  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;
                        }
                    });
                 }

problem问题
in end operation in top when check result i see some items are not related to their ID and have been moved.If there is no shift when I exit the parallel mode, all the identifiers are set correctly how resolve problem?在检查结果的顶部操作中,我看到一些项目与其 ID 无关并且已被移动。如果退出并行模式时没有移位,则所有标识符都已正确设置如何解决问题?

My suggestion is to use PLINQ instead of the Parallel class.我的建议是使用PLINQ而不是Parallel class。 It is a safer tool to use, for entry-level multithreading.对于入门级多线程,它是一种更安全的工具。 The PLINQ is like LINQ, but it starts with .AsParallel() . PLINQ 类似于 LINQ,但它以.AsParallel()开头。 It includes almost all of the familiar LINQ operators like Select , Where , Take , ToList etc.它包括几乎所有熟悉的 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);

The CallAPI method is assumed to have this signature: Task<APIResult> CallAPI(Item item);假定CallAPI方法具有以下签名: Task<APIResult> CallAPI(Item item);

This PLINQ query will process your data with a concurrency level of 4. This means that 4 operations will be concurrently in flight, and when one item completes the next one will start automatically.此 PLINQ 查询将以 4 的并发级别处理您的数据。这意味着 4 个操作将同时进行,当一项完成时,下一项将自动开始。

The ID s are expected to be unique, otherwise the ToDictionary operator will throw an exception. ID应该是唯一的,否则ToDictionary运算符将抛出异常。

This approach is suggested for its simplicity, not for its efficiency.建议使用这种方法是因为它的简单性,而不是它的效率。 The PLINQ is not really intended for processing I/O bound workloads, and will needlessly block ThreadPool threads while doing so. PLINQ 并不是真正用于处理 I/O 绑定的工作负载,并且在这样做时会不必要地阻塞ThreadPool线程。 You can look here for more efficient ways to throttle asynchronous I/O bound operations.您可以在此处查找更有效的方法来限制异步 I/O 绑定操作。

I have reached an answer.我已经找到答案了。 Which is as follows.如下。
Code代码

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