很多教程和資料都強調流暢的用戶體驗需要異步來輔助,核心思想就是保證用戶前端的交互永遠有最高的優先級,讓一切費時的邏輯通通放到後台,等到諸事完備,通知一下前端給個提示或者繼續下一步。隨著.NET發展,async和await關鍵字的推廣,Task Parallel Library (TPL)的穩步發展, 異步編程也越來越多的被重視和采用,很多時候非常便利的解決各種性能問題,但同時也帶來了很多的陷阱。
參考示例工程代碼下載地址:
------------------------------------------分割線------------------------------------------
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2014年資料/9月/10日/異步陷阱之IO篇
下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm
------------------------------------------分割線------------------------------------------
這裡我拋出一個實際項目中遇到的陷阱,先簡單交代一下故事背景:SpreadJS產品有一個Excel IO部件,是一個ASP.NET MVC Web API(MVC4)應用,用來導入Excel文件到SpreadJS中;其工作過程是客戶端先上傳Excel文件,服務器端接收文件後讀出內容,以SpreadJS特有的JSON格式回傳給客戶端。很長一段時間工作正常,直到某一天有一個“大神”級的客戶反饋他在使用Excel IO過程中會一定幾率隨機出現導入失敗,具體的表現是在返回的JSON數據中提示有IO錯誤,好吧,附上用戶場景的代碼片段(略去了腳本引用,DOM以及其他機密代碼):
$(document).ready(function() { // initialize 10 spreadjs widgets
for(var i = 0; i < 10; i++) {
$("#ss_" + i).wijspread({ sheetCount: 2 });
} // import handler
$("#importButton").click(function() { for(var i = 0; i < 10; i++) {
importToSpread("ss" + i);
}
}); // import process
function importToSpread(target) { var formData = new FormData();
formData.append("file", $("#importingExcelFile").get(0).files[0]);
formData.append("ExcelOpenFlags", "NoFlagsSet");
formData.append("TextFileOpenFlags", "None");
formData.append("Password", "");
$.ajax( {
url: "http://your.excelio.path/xsapi/import",
type: "POST",
success: function(data, textStatus, jqXHR) {
$("#" + target).wijspread("spread").fromJSON(JSON.parse(jqXHR.responseText).spread);
},
data: formData,
contentType: false,
processData: false,
headers: { "Accept": "application/json" }
});
}
});
也許各位看官可能有話說了:這明顯的窮折騰麼,有這麼把一個文件重復導入10次的實際場景嗎?嗯,這是一個社會工程學問題,略過,呵呵。
根據用戶的代碼,可以分析得到一些關鍵信息:
1、用戶在很短時間內快速提交了多個請求並上傳文件;
2、返回結果會隨機出現IO錯誤;
由此可以得出結論:應該是服務器處理上傳的Excel文件時,某個文件在特定情況下不可用,從而導致處理程序拋出IO異常。什麼情況會導致IO不可用呢?似乎一下子還真無從下手,作為開發人員,最容易想到的方法就是祭出IDE,直接掛上調試器,只要捕獲到這個IO異常就好了。經過幾次嘗試,終於看到了IO異常了,如下圖:
IO-Exception
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-09/106411p2.htm