前言
我们在运行某个比较耗时的功能的时候,如果不采用多线程的话界面会卡死不能动,这样不人性化。所以我们要使用多线程,达到一个在运行功能后,有一个进度条在滚动,并且界面不卡死可以随意移动的效果。
操作步骤
1、在窗体的构造函数中添加:
//不捕获对错误线程的调用
CheckForIllegalCrossThreadCalls = false;
举个栗子,创建控件label的线程是页面启动的主线程,如果在另一个线程修改label的值,这就是跨线程操作,而系统默认不允许这么做。所以我们要将CheckForIllegalCrossThreadCalls的属性设置为false,不捕获对错误线程的调用。但是允许跨线程访问相对不稳定,要慎用,对于简单的多线程事件问题不大。
2、在我们功能执行按钮事件中创建一个新线程并启动,新线程中的函数为我们的比较耗时的功能函数(以PIE辐射定标为例)。
private void simpleButton_OK_Click(object sender, EventArgs e)
{
//显示辐射定标正在进行中
mainForm.toolStripStatusLabel_status.Text = "辐射定标正在进行中......";
//显示进度条并开始滚动
mainForm.toolStripProgressBar_Main.Visible = true;
mainForm.toolStripProgressBar_Main.Style = ProgressBarStyle.Marquee;
//创建一个线程并启动
System.Threading.Thread myThread;
myThread = new System.Threading.Thread(new System.Threading.ThreadStart(myStartingMethod));
myThread.Start();
}
新线程中的函数myStartingMethod:
private void myStartingMethod()
{
#region 1、参数设置
PIE.CommonAlgo.DataPreCali_Exchange_Info info = new PIE.CommonAlgo.DataPreCali_Exchange_Info();
info.InputFilePath = textEdit_RasterDataFile.Text;
info.XMLFilePath = textEdit_MetadataFile.Text;
info.OutputFilePath = textEdit_OutputFile.Text;
//根据输出类型获得文件编码类型
//根据.分割textEdit_RasterDataFile.Text
string[] sArray = textEdit_RasterDataFile.Text.Split('.');
//获取文件后缀名
string type = sArray[sArray.Length - 1];
if (type == "tif" || type == "tiff") { info.FileTypeCode = "Gtiff"; }
else { info.FileTypeCode = "ENVI"; }
//设置Type 为100(表观辐射率)或200(表观反射率)
if (checkEdit_ApparentRadiance.Checked) { info.Type = 100; }
else { info.Type = 200; }
PIE.SystemAlgo.ISystemAlgo algo = PIE.SystemAlgo.AlgoFactory.Instance().CreateAlgo("PIE.CommonAlgo.dll", "PIE.CommonAlgo.CalibrationAlgo");
if (algo == null) return;
#endregion
#region 2、算法执行
PIE.SystemAlgo.ISystemAlgoEvents algoEvents = algo as PIE.SystemAlgo.ISystemAlgoEvents;
algo.Name = "辐射定标";
algo.Params = info;
bool result = PIE.SystemAlgo.AlgoFactory.Instance().ExecuteAlgo(algo);
#endregion
//算法执行成功
SuccessfulExecution = true;
//算法结束后关闭窗体
this.Close();
}
其中的SuccessfulExecution为全局bool变量,判断算法是否执行成功。
3、若执行成功,在窗体关闭后停止显示进度条,并加载结果,需要写在窗体关闭事件中:
private void RadiationCalibration_FormClosed(object sender, FormClosedEventArgs e)
{
if (SuccessfulExecution)
{
//停止显示辐射定标正在进行中
mainForm.toolStripStatusLabel_status.Text = "";
//不显示进度条停止滚动
mainForm.toolStripProgressBar_Main.Visible = false;
mainForm.toolStripProgressBar_Main.Style = ProgressBarStyle.Blocks;
//结果显示
ILayer layer = PIE.Carto.LayerFactory.CreateDefaultLayer(textEdit_OutputFile.Text);
mainForm.mapControlMain.FocusMap.AddLayer(layer);
mainForm.mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
}
}
上面三步就可以实现开始的动图效果了。
后来看PIE博客时发现PIE自带了异步调用,等我有时间了试一下:
PIE SDK算法的异步调用 - PIESAT - 博客园www.cnblogs.com