DBImport V3.7版本發佈及軟件穩定性(自動退出問題)解決過程分享

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);
            }
        }

好了,至此,穩定性的問題解決了,週末愉快!

 

發佈了55 篇原創文章 · 獲贊 25 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章