解決ArcEngine開發程序“假死”現象
在GIS數據處理中,數據量大是一個非常傷腦筋的問題。最近,在寫一個CAD註記轉Shapefile文件時,又遇到這個問題。
曾經處理一次數據,達130萬個點,即測試區域內的柵格轉成點全部處理,程序是寫好了,但速度之慢啊,關鍵問題是處理到一半報奇怪的錯誤,最後只好將數據分成6份,去實驗室開了6臺機子來分別處理,最後合成在一起。經歷過這件事後,我就去請教老師,他們在用程序處理GIS大數據時(特別是當數據帶有空間信息),怎麽來解決類似的問題?他總結了兩方面:一是硬件上,配置要高,對於特別大的數據考慮使用工作站或服務器來處理,GIS處理本來就是容易遇到這種情況;二是代碼上,要不斷優化,不該new的就不要new,能省則省,寫出比較節約內存和空間的代碼,需要不斷的積累和學習。
對於用戶來說,他們絕對不能容忍“假死現象”,一點擊“提交”程序界面就卡住了,如果強行進拖動界面容易出現未響應,直到程序關閉。
由於自己非計算機專業出身,對這類問題是束手無策,網上的解決方案是多線程,於是我嘗試去這樣做:
1 2 3 4 |
Thread MyThreadOne = new Thread( new ThreadStart(Main));
MyThreadOne.Name = "CADToShapeThread" ;
MyThreadOne.IsBackground = true ;
MyThreadOne.Start();
|
將原來直接寫的代碼放在一個Main函數中,然後新建一個Thread調用Main,執行結果就好多了,程序界面可以拖動了,數據在後臺處理。但由於不懂線程和進程,其安全問題也需要解決,要好好研究一下這個神奇的東西。
為了讓用戶知道程序還在處理,還沒有結果,得加一個進度條:當進程開始時,進度條出現,並不斷滾動顯示;當進程結束時,進度條隱藏。
但我在進程中訪問設置進度條的屬性失敗了,報錯:"Cross-thread operation not valid: Control ‘progressBar1‘ accessed from a thread other than the thread it was created on."百度說,這樣是不安全的,要用委托來解決,委托?又搞不懂了,得惡補呀。下面是最終解決方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/// <summary>
/// 設置控件參數
/// </summary>
/// <param name="oControl">控件</param>
/// <param name="propName">參數名稱</param>
/// <param name="propValue">參數值</param>
delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
private void SetControlPropertyValue(Control oControl, string propName, object propValue)
{
if (oControl.InvokeRequired)
{
SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
oControl.Invoke(d, new object [] { oControl, propName, propValue });
}
else
{
Type t = oControl.GetType();
System.Reflection.PropertyInfo[] props = t.GetProperties();
foreach (System.Reflection.PropertyInfo p in props)
{
if (p.Name.ToUpper() == propName.ToUpper())
{
p.SetValue(oControl, propValue, null );
}
}
}
}
|
解決ArcEngine開發程序“假死”現象