简体   繁体   English

C#Parallel.ForEach抛出indexOutOfBoundException

[英]c# Parallel.ForEach throwing indexOutOfBoundException

I'm using a lot of parallel foreach loops. 我正在使用许多parallel foreach循环。 they are mostly used for elaborating datas and after add them to a list. 它们主要用于详细说明数据并将其添加到列表中。

this is an example of my methods: 这是我的方法的一个例子:

System.Threading.Tasks.Parallel.ForEach(magazzini, m =>
{
    try
    {
        warehouse.Add(new WAREHOUSE()
        {
            ID = m.Id,
            NAME = m.new_name,
            CODE = m.new_codice,
            INTEGRATION_KEY = m.dynamics_integrationkey,
            RESOURCE_ID = m.new_mobileuser == null ? Guid.Empty : m.new_mobileuser.Id
        });
    }
    catch (Exception ex)
    {
        Logging.Error(authToken, string.Format("GetAllMagazzini|Magazzini|{0}", ex.InnerException));
    }
});

I read in this old post that it might be caused by the not thread-safe property of the List<T> . 我在这篇旧文章中读到它可能是由List<T>的非线程安全属性引起的。 My problem is the following: 我的问题如下:

I have those not only for loops like this but also for long loops with a lot of operations. 我不仅拥有像这样的循环,而且拥有很多操作的长循环。 I had to use the parallel.foreach because using the classic foreach makes the query to timeout, since it's on a WebService. 我必须使用parallel.foreach因为使用经典的foreach会使查询超时,因为它在WebService上。

How can I use the parallel.foreach avoiding the indexOutOfBoundException ? 我如何使用parallel.foreach避免indexOutOfBoundException I have to change the List<T> in something else? 我必须在其他地方更改List<T>吗?

Yes, change List<T> to ConcurrentBag<T> since the resizing of the backing array in List<T> will cause problems with concurrent write operations. 是的,将List<T>更改为ConcurrentBag<T>因为在List<T>调整后备数组的大小将导致并发写入操作出现问题。 Another option is to create a lock around the add operation. 另一种选择是在添加操作周围创建一个lock

If there are no other operations that adding in your Parallel.ForEach concurrency is not necessary and will even negatively impact performance. 如果没有其他操作需要添加到Parallel.ForEach并发中,这将对性能产生负面影响。 If that is the case, create a regular foreach or use AddRange . 如果是这种情况,请创建一个常规的foreach或使用AddRange

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM