求优化利用异步线程生成shp文件时,速度比没加线程慢了三倍。
求优化在生成shp文件时,由于数据有点多,程序界面会出现卡死的假象,实际上程序还是处在运行状态。为了知道程序运行到哪里并解决假死的现象,我添加了一个异步进度条后能够知道程序正在处理哪一行数据,但是处理效率实在是太慢了。求大家支招优化:有没有什么方法能知道程序运行进度,并解决假死现象
#region 创建文件窗体
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Shape文件(*.shp)|*.shp";
saveFileDialog.Title = "新建点形shp文件";
saveFileDialog.CheckFileExists = false;
DialogResult dialogResult = saveFileDialog.ShowDialog();
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
int index;
string fileName;
//string filePath;
string fileFullPath;
if (dialogResult == DialogResult.OK)
{
fileFullPath = saveFileDialog.FileName;
index = fileFullPath.LastIndexOf(@"\");
fileName = fileFullPath.Substring(index + 1);
filePath = fileFullPath.Substring(0, index);
if (System.IO.File.Exists(saveFileDialog.FileName))//检查文件是否存在
{
if (MessageBox.Show("该文件夹下已经有同名文件,替换原文件?", "询问", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
IFeatureWorkspace FWS = pWorkspaceFactory.OpenFromFile(filePath, 0) as IFeatureWorkspace;
IFeatureClass pFeatureClass = FWS.OpenFeatureClass(fileName);
IDataset pDataset = pFeatureClass as IDataset;
pDataset.Delete();
}
//System.IO.File.Delete(saveFileDialog.FileName);
else
return;
}
}
else
{
fileFullPath = null;
return;
}
#endregion
//显示进度条
ProgressForm progressForm = new ProgressForm();
progressForm.Show();
// Prepare the background worker for asynchronous prime number calculation
//准备进度条的记数
worker = new BackgroundWorker();
// Specify that the background worker provides progress notifications
//指定提供进度通知
worker.WorkerReportsProgress = true;
// Specify that the background worker supports cancellation
//提供中断功能
worker.WorkerSupportsCancellation = true;
// The DoWork event handler is the main work function of the background thread
//线程的主要功能是处理事件
//开启线程执行工作
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
// Specify the function to use to handle progress
//指定使用的功能来处理进度 调用worker_ProgressChanged事件
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
//调用进度条窗体,刷新进度
worker.ProgressChanged += new ProgressChangedEventHandler(progressForm.OnProgressChanged);
// Specify the function to run when the background worker finishes
// There are three conditions possible that should be handled in this function:
// 1. The work completed successfully
// 2. The work aborted with errors
// 3. The user cancelled the process
//进度条结束完成工作
//1.工作完成
//2.工作错误异常
//3.取消工作
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progressForm.OnProcessCompleted);
//数据来源
worker.RunWorkerAsync(dtContact);
//单线程执行工作
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
MovedataTable((BackgroundWorker)sender, e);
}
//进行取值工作
private void MovedataTable(BackgroundWorker worker, DoWorkEventArgs e)
{
System.Data.DataTable datable = e.Argument as System.Data.DataTable;
for (int i = 0; i < datable.Rows.Count;i++ )
{
// Check for cancellation
//检查取消
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
// This will be handled in the correct thread thanks to the
// internals of BackgroundWroker and AsyncOperation
worker.ReportProgress((i + 1) * 100 /datable.Rows.Count, datable.Rows[i]);//datable.Rows[i]传索引为i的某行数据
// Simulate some time consuming proccess.
//线程休眠
Thread.Sleep(500);
}
}
}
//绘制shp文件
public void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{IWorkspaceFactory pShpWksFact = new ShapefileWorkspaceFactory();
IFeatureWorkspace pFeatWks;
pFeatWks = (IFeatureWorkspace)pShpWksFact.OpenFromFile(filePath, 0);
DataRow dataRow = e.UserState as DataRow;
double pointX, pointY;
//注意不要经纬度写反 x代表经度,y代表纬度
pointX = double.Parse(dataRow["经度"].ToString());
pointY = double.Parse(dataRow["纬度"].ToString());
ESRI.ArcGIS.Geometry.IPoint pPoint = new PointClass();
pPoint.PutCoords(pointX, pointY);
IFeature pFeature = pFeatureClass2.CreateFeature();
pFeature.Shape = pPoint;
//为该点添加所有的属性值
pFeature.set_Value(pFeature.Fields.FindField("日期"), dataRow["日期"]);
pFeature.set_Value(pFeature.Fields.FindField("时间"), dataRow["时间"]);
pFeature.set_Value(pFeature.Fields.FindField("纬度"), dataRow["纬度"]);
pFeature.set_Value(pFeature.Fields.FindField("经度"), dataRow["经度"]);
pFeature.set_Value(pFeature.Fields.FindField("震源深度"), dataRow["震源深度"]);
pFeature.set_Value(pFeature.Fields.FindField("震级"), dataRow["震级"]);
pFeature.set_Value(pFeature.Fields.FindField("地震类型"), dataRow["地震类型"].ToString());
pFeature.set_Value(pFeature.Fields.FindField("位置"), dataRow["位置"].ToString());
//保存操作
pFeature.Store();
}
[解决办法]
ProgressChanged里的代码是在UI线程里执行的,所以会卡界面,能移到线程里执行最好,不能的话,在
ProgressChanged里加上 Application.DoEvents();试试
[解决办法]
你这是简单的存储的IO操作?还是更新数据库的操作
前者的话:涉及到硬盘的写速度,个人感觉基本没有优化的空间了,除非特别犀利的算法
后者的话:可以考虑3L提出的linq的并行,前提是有多个cpu