C#使用Process调用批处理阻塞问题
PS:又见到熟悉的C#代码了,好开心,哈哈哈。这次又跳坑了,好不容易才爬起来。
公司有自己开发的一套Submit、Compile、Publish的生命周期系统。
在Compile时,需要调用外部的编译程序进行源代码的编译工作。
android的哥们最近换了打包的工具,从ant换成了gradle,于是需要系统支持gradle的编译。
gradle的配置、原理就不讲了,自行google就可以了。
写了一个带参数的批处理,来调用gradle进行编译打包。然后在C#中使用process进行关联调用。
在由于这个是后台调用,而且需要拿到编译的output和error,当然需要进行output和error的重定向。
(在查找批处理问题时,可以先放弃重定向,让结果直接输出在控制台中)
这时,出现了一个很令人费解的问题,关联调用的批处理,被莫名的阻塞掉了。在process等待超时,继续执行之后,批处理才会继续执行。
调试时发现一个情况,在超时之后,读取输出信息时,访问standoutput属性,会有一个类似溢出的报错信息。
于是google了输出重定向的相关知识,才发现批处理阻塞,正是跟这个报错有关。
先说下个人对于输出重定向的理解。
如果process设置了输出重定向,会设置一个输出的缓冲区,将process关联的程序输出结果写入缓冲区。
process通过不断的读取缓冲区的内容,来清空缓冲区。
缓冲区的空间是有限的,如果process没有进行数据读取,那么在某一时刻,缓冲区会被填满。
然后,关联进程会等待缓冲区的数据清空,而此时process在等待关联进程结束。于是,死锁发生了。
解决方法:
在启动process后,进行输出缓冲区的读取操作
由于读取方法内部会一直阻塞至关联进程结束。为了保证主线程不被阻塞,一般是使用线程异步读取缓冲区的内容。
注意:线程的启动,要在Start方法之后,WaitForExit方法之前。
另:会进行输出的重定向有两个,output和error,两个都有类似问题,请保证处理完全。