標籤:沒反應 orm highlight efault 技術 span 多次 tco 點擊
DBImport V3.7介紹:
1:先,再介紹亮點功能:
主要的升級功能為:
1:增加(Truncate Table)清表再插入功能:
清掉再插,可以保證兩個庫的資料一致,自己很喜歡這個功能。
2:資訊列增加紅色部分:
黑色的資訊太多,有時候錯誤資訊被淹陌,分拆出來單獨紅色塊標識錯誤資訊,清晰一些。
3:增加儲存所有的配置及配置還原:
之前只儲存資料庫連結的配置,為了第4點,包起了所有的配置,包括表名等。
4:增加自啟動參數,用於定時功能的開機啟動:
自啟動參數為 - true 或 - 1,下一版本會處理成服務,支援重啟電腦後繼續服務。
5:解決軟體穩定性(自動結束)問題。
:點擊下載
下面重點介紹解決問題的過程:
記得我發布ASP.NET Aries架構的時候,有個示範地址:http://aries.cyqdata.com 。
由於總有個人別刪除使用者或資料或修改登陸密碼,為了防止此種情況:
我把DBImport放到伺服器,同時開啟了定時功能,以為可以一勞永逸了。
結果軟體運行運行著,就自動結束了,然後又得手工執行一次。
所以目前在執行的方案,鎖定了檔案的唯讀屬性,來避免使用者修改資料。
今天剛好想起來,於是就想到要解決它了,於是就有了以下的內容:
解決的過程:1:先確認情況:
單獨運行軟體,開啟定時功能,然後出去溜達一圈,回頭再看結果:
多次確認後,而且問題不單純:
A:卡住沒反應。
B:拋異常定義到Application.Run(單獨運行時表現直接退出軟體)。
2:通過IntelliTrace查看異常:
開啟了”IntelliTrace事件和調用資訊“:
F5運行,拋:“嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞”。
我以為找到問題,結果是掉坑裡。
1:當一個方法返回數組T[] GetList()時,拋這個異常。2:當Dictionary添加一個數組Add(key,T[])時,拋這個異常。3:當方法的參數為:public MDataTable Select(params object[] selectColumns) 這種數組時,拋這個異常。
好吧,這數組是哪裡得罪了微軟,要被它這麼欺負。
改了半天代碼,把T[]數組的代碼全改成List<T>,一般又一步,走向正常運行。
後來沒折了,畢竟有些公開的方法有params參數不好改,只好把選項改成“僅IntelliTrace事件”。
運行,等出Bug後,點一下全部中斷:
然後就可以看到執行的事件了:
結合著自己記錄的錯誤資訊:
回頭審了一下代碼,終於發現一個Bug:
if (isGoOn) { using (SqlBulkCopy sbc = new SqlBulkCopy(con, (keepID ? SqlBulkCopyOptions.KeepIdentity : SqlBulkCopyOptions.Default) | SqlBulkCopyOptions.FireTriggers, sqlTran)) { sbc.BatchSize = 100000; sbc.DestinationTableName = SqlFormat.Keyword(mdt.TableName, DalType.MsSql); sbc.BulkCopyTimeout = AppConfig.DB.CommandTimeout; foreach (MCellStruct column in mdt.Columns) { sbc.ColumnMappings.Add(column.ColumnName, column.ColumnName); } sbc.WriteToServer(mdt); } } if (_dalHelper == null) { con.Close(); con = null; } else if (isCreateDal) { _dalHelper.EndTransaction(); _dalHelper.Dispose(); }
這段代碼,在異常的時候,連結關閉不了,重點它還是開了事務的,沒想到都老江湖了,百密還是有一輸。
於是運行久了,串連池耗盡,加上事務卡死雙重打擊,介面就進入長時間卡死不動了。
找到問題修正就好了,關閉連結的放到Try的finally去:
finally { if (_dalHelper == null) { con.Close(); con = null; } else if (isCreateDal) { _dalHelper.EndTransaction(); _dalHelper.Dispose(); }}第2個問題:自動結束的問題,有過經驗。
畢竟當年創業寫微博粉絲精靈的時候,就遇到過了:
對於Winform軟體,不要線上程裡操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false;
於是,把所有的代碼都改成主線程委託調用的方式,類似以下代碼:
private delegate void SetTextHandle(string id, string value); private void ThreadSetText(string id, string value) { this.Controls.Find(id, true)[0].Text = value; } private void SetText(string id, string value) { if (this.InvokeRequired) { this.Invoke(new SetTextHandle(ThreadSetText), new object[] { id, value }); } else { ThreadSetText(id, value); } }
好了,至此,穩定性的問題解決了,周末愉快!
DBImport V3.7版本發布及軟體穩定性(自動結束問題)解決過程分享