小记:目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。

异常:System.ArgumentException: 目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。(不好意思忘记截图了)

发生异常的代码如下:

var list = new List<Topic>();
Parallel.For(2, totalPage + 1, page =>
{
    //AddRange 方法发生异常
    list.AddRange(GetTopics(board.BoardID, page));
});

原因:List<T> 集合不是线程安全的,在并发操作 List 时,内部计算可能会出现问题。(具体内部会出现什么问题,我这个菜鸟在这里就不卖弄了,大家可以反编译看看 List 内部实现原理)

经过在StackOverflow上查找得知2种解决方法:以下为原回答截图

地址:http://stackoverflow.com/questions/8796506/correct-way-to-guarantee-thread-safety-when-adding-to-a-list-using-parallel-libr

即:第一种,使用 lock 加锁

private static readonly object locker = new object();
Parallel.For(2, totalPage + 1, page =>
{
    var range = GetTopics(board.BoardID, page);
    lock(locker)
    {
        list.AddRange(range);
    }
});

第二种,使用 AsParallel().SelectMany 并发生成一个 Enumerable

//生成一个整数序列
var nums = Enumerable.Range(2, totalPage - 1);
//使用 AsParallel 执行并发操作,并使用 SelectMany 将每个元素映射为新的对象,然后将结果合并为一个集合
var range = nums.AsParallel().SelectMany(page => GetTopics(board.BoardID, page));
//同步增加到 List 中
list.AddRange(range);

经过在MSDN上查找,发现有一个命名空间下实现了一些线程安全集合类,如下图

地址:https://msdn.microsoft.com/zh-cn/library/system.collections.concurrent(v=vs.100).aspx

上面这些线程安全集合类我暂时没有用过,不过既然是微软提供的,想必性能各方面都应该不错,大家可根据适用场景自行选择。

时间: 2024-10-13 06:39:22

小记:目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。的相关文章

C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”

调用外部dll时,出现如下问题 C# DllImport“调用导致堆栈不对称.原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配.请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ” 后来经过仔细检查发现,误把vb中的longx型当成64位,实际上它相当于C#中的32位int型.

托管调试助手 &quot;PInvokeStackImbalance&quot;:的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管

在C#中一定要检查引用时的数据类型 WinAPI 的数据类型 默认是32位的,但是引用时外部的是 Long类型默认是64位的.所以引用时需要将 long 改为 int 型. 参照 http://blog.sina.com.cn/s/blog_8248282d0101hcbd.html https://blog.csdn.net/jinhuicao/article/details/83584973 情况一: 对 PInvoke 函数"TestDLL!TestDLL.Form1::mySum&quo

未排序数组中累加和为给定值的最长子数组长度

题目:给定一个数组arr,该数组无序,但每个值均为正数,再给定一个正数k.求arr得所有子数组中所有元素相加和为k的最长子数组长度. 解答:最优解可以做到时间复杂度为o(n),额外空间复杂度为o(1).首先用两个位置来标记子数组的左右两头,记为left和right,开始时都在数组的最左边(left=0,right=0).整体过程如下: 1.开始时变量left=0,right=0,代表子数组arr[left......right]. 2.变量sum始终表示子数组arr[left......righ

2016/07/07 apmserv5.2.6 Apache启动失败,请检查相关配置。MySQL5.1已启动。

因为要用PHP做一个程序,在本机上配PHP环境,下了个APMServ5.26,安装很简单,不再多说,装好后,启动,提示错误,具体是:“Apache启动失败,请检查相关配置.√MySQL5.1已启动”,然后就在网上找解决办法,倒是找到不少,但都没有解决问题,差点就想换一个集成环境了.不过知难而进一向是我的原则,最后终于解决了,现在把所有解决步骤整理出来,希望能对碰到同样情况的朋友有所帮助,如果有有朋友碰到新的情况,欢迎同我交流.另外如果大家有自已各方面经验,欢迎在阳关道网站上发布出来跟大家共享一下

Nuget.config格式错误,请检查nuget.config配置文件

安装 VS 2015 Professional 版,安装后,我想加一个nuget的包配置. 然后提示我:Nuget.config格式错误,请检查nuget.config配置文件 我找到了 Nuget.config 文件,并没有发现有什么问题.修改了也没用,并且里面的配置 与 VS 的nuget 显示的不一样. Nuget.config:{C:\Users\Administrator\AppData\Roaming\NuGet\NuGet.Config} 由于全部安装比较大,我只选择了部分内容安装

IOS 京东相关app 出现“网络请求失败,请检查您的网络设置”的解决办法

问题情况 在IOS系统下,下载安装或者更新新版的京东相关app之后,打开app直接就是“网络请求失败,请检查网络设置”,无论是数据连接还是wifi都试了,都是网络请求失败. 然而打开无线局域网-使用无线局域网与蜂窝移动的应用…却找不到手机京东这个对应的app.这是什么原因呢???!!卸载重装还是这个老样子! 解决办法 1.先进入那个“使用无线局域网与蜂窝移动的应用”的界面,随便把某个应用的的联网权限改成别的. 2.再次打开京东这个app,系统就会提示你选择联网权限,选择允许. 3.回去“使用无线

记录一次MVC 3.0错误 HTTP 404您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。

在部署到IIS7时,MVC3报了一个找不到资源的错误,文件肯定是有的,而且页面是肯定报错的,也就说内部运行错误了,而MVC把错误没有抛出来而已: 所以对症下药,发觉我的项目里面用了rexs进行多语言,然后发现App_GlobalResources这里面的文件夹是空的,按道理来说,不应该是没有文件才对. 所以我把App_GlobalResources文件夹重新上传即可,问题解决. 以上是我的问题解决,以下我将介绍其它的类似的问题处理方法: 一.路径配置问题(转载) 有时在程序运行的时候会出现“HT

warning MSB3245: 未能解析此引用。未能找到程序集“CemeteryBLL”。请检查磁盘上是否存在该程序集。 如果您的代码需要此引用,则可能出现编译错误。

多层架构,在每次重新生成解决方案的时候,老是提示:warning MSB3245: 未能解析此引用.未能找到程序集"CemeteryBLL".请检查磁盘上是否存在该程序集. 如果您的代码需要此引用,则可能出现编译错误. 但是如果逐个生成,那就没问题.这是因为在多层架构中,项目之间有引用关系,比如三层架构,UI界面层引用了BLL业务层,BLL业务层引用了DAL数据层,如果我们全部生成解决方案,它生成的顺序如果不是先从DAL再BLL最后UI层,则会提示上面那个错误.因为如果先生成UI层,那

DirectX 安装报错: 不能信任一个安装所需的压缩文件,请检查加密服务是否启用并且cabinet文件证书是否有效

DirectX 安装报错 不能信任一个安装所需的压缩文件,请检查加密服务是否启用并且cabinet文件证书是否有效 是直播软件open broadcaster software,这个软件安装的时候提示"your system is missing DirectX components that Open Broadcaster Software requires.Would you like to download them?"然后点是,就跳转微软的官方下载页面了. 下载dxwebse