|
1、问题的提出 在桌面应用中,经常需要用后台线程处理数据,然后将数据更新到地图上显示。 由于MapInfo.Engine内部线程管理机制,从主线程(也就是创建MapControl控件实例的线程)之外的线程不能直接调用MapInfo.Engine.Session.Current.Catalog来获取地图的编录。 2、解决方法 利用 mapControl1.InvokeRequired 检测是否需要通过Invoke机制更新mapContrl1控件。当对mapControl1更新的调用方位于创建mapControl1控件所在的线程以外的线程时mapControl1.InvokeRequired = true 3、示例 ------------------------------------------------------------- 后台线程:采集GPS定位信息并更新地图 ------------------------------------------------------------- /// <summary> /// 采集 GPS 定位信息的类 /// </summary> public class GPS { public delegate void OnNewPositionInfoHandler( float lati, float longti); public event NewPositionInfoHandler OnNewPositionInfo; private int m_interval; /// <summary> /// 构造函数 /// </summary> /// <param name="interval">定时更新时间间隔(毫秒)</param> public GPS(int interval) { m_interval = interval; Thread t = new Thread(new ThreadStart(WorkThread)); t.IsBackground = true; t.Start(); } /// <summary> /// 后台线程。接收并处理来自GPS的定位信息并更新地图 /// </summary> private void WorkThread() { while(true) { Thread.Sleep(m_interval); //这里只是模拟采集到来自GPS的定位信息 float longi = 32.120201010; float lati = 118.39312781; // 引发事件更新地图 if(OnNewNewPositionInfo != null) OnNewPositionInfo( lati, longti); } } } ------------------------------------------------------------- 在Windows窗体代理中 ------------------------------------------------------------- private GPS gps = null; public delegate UpdateInfoHandler( float lati, float longti); private void Form1_Load(object sender, System.EventArgs e) { gps = new GPS( 1000 ); // 1秒钟更新一次 gps.OnNewPositionInfo +=new GPS.OnNewPositionInfo(Form1_OnNewNewPositionInfo ); } private void Form1_OnNewPositionInfo( float lati, float longti) { if(mapControl1.InvokeRequired) { object[] para = {lati, longti}; mapControl1.BeginInvoke( new UpdateInfoHandler(UpdateInfo), para); } else UpdateInfo( lati, longti); } void UpdateInfo( float lati, float longti) { MIConnection cnx = new MIConnection(); try { cnx.Open(); MICommand cmd = cnx.CreateCommand(); cmd.CommandText = string.Format("update s3064 set latitude = {0}, longtitude={1} ", lati, longti); cmd.ExecuteNonQuery(); mapControl1.Map.Layers[0].Invalidate(); } catch{} finally { cnx.Close(); } }
|