记VS2013并行编译导致出错的解决过程

  接前一篇,电脑换了新的,系统是64bit的win8系统,先安装了SQLServer2012,再安装VS2010旗舰版,Stop!为什么还是2010?因为2010太经典了,以至于公司的项目还在用它写项目,而我是直接从公司那拉过来的项目文件(含所有相关文件的Solution解决方案)。因为解决方案就是用2010创建的,因此直接用2010加载解决方案几乎没有问题,为了保证工作稳定,所以一定要装VS2010啊!但是问题来了,我心目中最爱的VS2013啊,什么时候能用上呢?这就涉及到了项目版本移植,接下来进入正题。

  VisualStudio可以安装多个版本,但是一定要要从地版本装起,然后装高版本。基本上来说高版本的解决方案不能在低版本的VS中打开(.sln文件),但是高版本VS却可以打开低版本创建的.sln文件,这里高版本VS会将低版本.sln文件转换为高版本。而项目文件一般来说不受影响,而且加载已经存在的项目文件(.csproj文件)是不会更改目标生成框架版本(也就是.NET版本号)。我公司的项目用2010创建,.NET框架是4.0。这些都没有问题。可是我编译生成asp.net mvc application项目时却报错,肯定不是代码的问题,因为之前用2010加载过。查看错误信息发现是缺少程序集,翻找各个类库项目发现有些项目的引用标有黄色叹号,将这些引用Remove后重新添加,再次生成仍然报错。

  到底是怎么回事呢?根据错误列表,一个一个去找,从最底层的类库开始生成,最后锁定一个项目(假定该项目名为Trouble)。这个项目每次编译生成操作均会报错,引用的程序集中也没有黄色叹号的,再查看输出窗口中的生成信息,发现其中一个引用项目(假定该项目名为CauseA)生成失败,失败的原因是项目CauseA引用的一个项目(假定该项目名为CauseB)不存在。回头查找项目CauseA和CauseB,由于A引用B,因此先重新生成B,生成成功,再生成A,也生成成功!然后来生成项目Trouble,依然报错,错误信息还是项目CauseA引用的项目CauseB不存在。仔细查看输出窗口的信息,发现每个引用程序集生成信息都带有编号,而还有这种现象:1号程序集编译开始,接下来并不是1号程序集的生成信息,而是2号程序集编译开始,3号程序集编译开始,然后又回到了2号程序集的生成信息,3号程序集生成信息,2号程序集生成成功。。。这说明什么啊?这时脑海中有个猜想,难道VS编译生成时用了多线程?应该是这样了。这时再看项目Trouble的引用,发现它同时引用了项目CauseA和CauseB,这里说明一下三个项目关系:Trouble引用A和B,A引用B,可以肯定一点,这里不存在循环引用的错误。当然可能你会说,即使不存在循环引用,但是这样的引用关系也是不规范。可是公司给的就是这套代码,我暂时还不能改结构。我想VS这里执行编译生成操作,应该用了多线程,而输出窗口信息是B开始编译=>A开始编译=>A生成出错=>A生成失败=>B生成=>B生成成功,这样看来只要让B生成成功在A开始编译之前就可以。也就是我现在需要编译生成的操作顺序执行,而不是多线程乱序执行。那么VS有没有设定编译生成是否使用多线程执行的选项?菜单栏=>Tools=>Projects and Solutions=>Build and Run中我赫然发现了第一行:

  4  maximum number of parallel project builds

那个4是在文本框中,我没装中文版,这个意思是项目生成的最大并行数,这不就是多线程并行执行嘛!于是乎,将这个“4”改为“1”,保存后重新生成,输出窗口信息中已经没有了程序集编号,而是按照程序集引用顺序依次编译生成,最后结果生成成功。至此,我的问题解决,整个解决方案生成成功,可是依然还有问题。

  后续问题列表:

    1、我这次遇到问题的情况中,项目CauseB在程序集引用排序中恰好排到了项目CauseA的前面,当取消并行生成后,自然先生成B后生成A,不会出错,但是万一A排到了B前面,那岂不是永远都不会生成成功了吗?

    2、我回头又翻看了VS2010旗舰版中文版,里面也有这个选项“最大并行项目生成数”,设置的也是4,但是在VS2010中从来没有出现过这个问题,这是什么原因?难道2010软件的多线程执行方式(不是指编写代码的多线程执行方式,而是IDE软件程序本身的多线程执行方式)与2013软件的多线程执行方式不一样?

    3、一个项目引用的所有程序集,在生成时的排序VS是如何处理的?能否制定某个程序集排在另一个程序集之前吗?

  最后,还要啰嗦几句前几天碰到的一个SQLServer2012的问题。有人可能说了,这还是技术博客吗?当然不是了,这只是问题的解决过程的备忘,这里也没有什么技术知识点。看到这里的同学别说被我欺骗了,如果你遇到了同样的问题,我想还是能让你少走一些弯路的。公司的OA系统会注册电脑的Mac地址和计算机名称,每个网卡硬件都有一个Mac地址,而软件程序在获取Mac地址,基本不会直接访问硬件,而是通过操作系统来获取,那么操作系统如何存储这个信息呢,答案是存放在注册表中,所以虽然我换了电脑,只要将注册表中的Mac地址信息更换即可。几年前,我还是百度之后进入注册表修改对应键值,但是现在好多软件(如软媒魔方)已经集成了这项功能。而由于新电脑是品牌机,因此计算机名称默认为Lenovo-PC,还需要改成以前的。就改了这个计算机名称后,我就遇到了一个问题,但是当时还没发现。

  具体过程是我先装SQLServer2012,再装VS2010(会同时装一些SQLServer2008 Express版的部分功能,如果先装VS后装SQL,会可能出现无法安装的问题),能够连接本机数据库,连接时也没仔细看,数据库服务器名称直接用默认的Lenovo-PC。而后我又装了VS2013,其中提示我要安装SQLServer local DB,这个版本的SQLServer是专门给开发人员配合VS使用的,其实它挺好,但是用惯了SQLServer企业版,就没使用它。之后,也就是改了计算机名称,且安装了VS2013和SQLServer local DB之后,再次连接本机数据库,发现连接不上了,报错信息大概为“未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。”。这时我完全忘记了我改过计算机名称且服务器的名称用计算机名称这一档子事,首先反应的是我的数据库远程配置没开、数据库管道连接方式中TCP/IP未启用、数据库相关服务意外中止等等。进行相关检查后,发现一切都好好的,为什么就是连接不上本机数据库呢?于是我百度之,用给出的报错信息搜索,可是没有人提出要检查计算机名称是否正确,因为这个错误太低级了吧!不是程序员应该犯的。百度绝大部分是说当安装完SQLServer2008后,再安装VS2013时根据提示安装了SQLServer2012Express local DB,原来的SQLServer2008无法使用,解决办法是卸载SQLServer2012Express local DB。可我之前安装的不是SQLServer2008,就直接安装了SQLServer2012啊!然后我又进了计算机管理中,发现服务中有两个SQLServer配置器,其中一个是2012版本,里面的各项服务都处在正确运行中,而另一个是2008版本,数据库服务中报错了,当时就想,难道是这个引起的无法连接本机数据库吗?于是乎,接下来尝试了修复SQLServer2012(相当于重装SQLServer2012),结果不幸;又尝试了卸载VS2013,结果还是不行;再卸载SQLServer2012Express local DB,结果依然不行。。。最后再打开SQLServer Management的注册服务器窗口时,突然看到Lenovo-PC,想起了我更改过计算机名称。于是乎尝试用新计算机名称连接,一下子就成功了,泪水啊!一个低级错误折腾了这么多。这里之所以没想到这个原因,主要因为之前的数据库名称基本在用127.0.0.1(本机数据库服务器名称主要可以用127.0.0.1或网内IP地址、localhost、计算机名称),还有就是计算机名称几乎不会改动。之后又重装了VS2013,本机数据库仍然可以正常连接。

  由此我还想到了曾经配置IIS站点遇到的问题,当时BOSS为了保证公司数据的安全,责令网络管理员把服务器Windows用户的密码给改掉。改完之后,访问我写的公司网站全都访问不了。BOSS不明所以,以为我写的代码又出问题了,让我尽快改好。我当时也没改动代码,而且在我本机上运行也很好,到底是什么原因呢?找到了网络管理员,跟他一块儿排查,最后发现IIS应用程序池和站点是可以关联Windows用户,当关联的Windows用户有密码时,同时要提供正确的密码,IIS服务器才能以这个Windows用户身份访问服务器上的文件。而网络管理员改了Windows用户密码之后,没有在这里更改对应的密码,导致Windows用户身份验证失败,而无法访问网站。

  因此以后排查错误时也要注意服务器名称、IP地址、计算机名称、操作系统用户及密码等是否正确,可以提高解决问题的效率,这次总结经验教训就到这里。

上一篇:linux下代替system的基于管道的popen和pclose函数


下一篇:HDU_2034——集合A-B