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,兩個都有類似問題,請保證處理完全。