1.不带参数的多线程
Thread spatialQueryThread = new Thread(spatialQuery);
spatialQueryThread.Start();
private void spatialQuery()
{
}
2.带参数多线程
Thread readMxdThread = new Thread(new ParameterizedThreadStart(readMxd));
readMxdThread.Start(this.txtMxdPath.Text);
private void readMxd(object path)
{
}
3.跨线程操作窗体控件
访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
.NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题。在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并显示以下消息:“从不是创建控件***(控件名称) 的线程访问它。”
可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常。这会使控件以与在 Visual Studio 2003 下相同的方式运行。
下面的代码示例演示如何从辅助线程以线程安全方式调用 Windows 窗体控件:
private delegate void InvokeDelegate(object o);// 代理
//打开地图文档
private void btnOpenMXD_Click(object sender, EventArgs e)
{
OpenFileDialog ofd=new OpenFileDialog();
ofd.Filter = "arcgis mxd文件|*.mxd";
if (ofd.ShowDialog() == DialogResult.OK)
{
this.labState.Text = "正在加载地图文档,请稍候...";
this.txtMxdPath.Text = ofd.FileName;
Thread readMxdThread = new Thread(new ParameterizedThreadStart(readMxd));
readMxdThread.Start(this.txtMxdPath.Text);
}
}
//使用新的线程读取文档
private void readMxd(object path)
{
try
{
IMapDocument mapDocument = new MapDocument(); //地图文档对象
mapDocument.Open(path.ToString(), "");
IFeatureLayer pFeatLayer = this.getLayerByName(mapDocument.Map[0], "单元网格") as IFeatureLayer;
if (pFeatLayer == null)
{
MessageBox.Show("不存在单元网格图层");
}
this.pCellFeatCls = pFeatLayer.FeatureClass;
readMxdComplete(null);
}
catch (Exception ex)
{
readMxdError(null);
}
}
//改变状态标签
private void readMxdComplete(object o)
{
if (this.InvokeRequired)
{
InvokeDelegate invoke = new InvokeDelegate(readMxdComplete);
this.Invoke(invoke, o);
}
else
{
this.labState.Text = "地图文档加载完成!";
if (this.conn != null)
this.btnQueryIntersectArea.Enabled = true;
}
}
//改变状态标签
private void readMxdError(object o)
{
if (this.InvokeRequired)
{
InvokeDelegate invoke = new InvokeDelegate(readMxdError);
this.Invoke(invoke, o);
}
else
{
this.labState.Text = "就绪";
}
}