利用BackgroundWorker控件异步读取shp文件


在WinForm中,当执行一些耗时任务时,因响应时间较长而导致窗体假死是一种常见问题。这时我们往往会想到单独开一个线程执行任务,同时显示当前任务的执行进度。但.NET并不允许跨线程访问UI,因为UI都是创建在主线程当中的,若跨线程访问会导致不可预计的问题出现。较为常用的是利用委托,把更新UI状态的代码Invoke到主线程,这是较为常用的一种方法。除此之外,WinForm提供了一个BackgroundWorker组件,它能够使我们更加简单地实现异步读取的功能。这里利用ArcEngine读取shp文件,同时利用BackgroundWorker组件防止界面假死。代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.SystemUI;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private IFeatureClass pFeatureClass;

        // 构造函数
        public Form1()
        {
            InitializeComponent();
            pFeatureClass = GetFeatureClass(@"D:\Users\DSF\Desktop\data\ZD.shp");
            pgbReadStatus.Maximum = pFeatureClass.FeatureCount(null);
        }

        // 执行任务
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, true);
            IFeature pFeature = pFeatureCursor.NextFeature();
            while (pFeature != null)
            {
                if (bw.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                // YSDM
                int fieldIndex_YSDM = pFeature.Fields.FindField("YSDM");
                string fieldValue_YSDM = pFeature.get_Value(fieldIndex_YSDM).ToString();

                // DKMC
                int fieldIndex_DKMC = pFeature.Fields.FindField("DKMC");
                string fieldValue_DKMC = pFeature.get_Value(fieldIndex_DKMC).ToString();

                // DKBM
                int fieldIndex_DKBM = pFeature.Fields.FindField("DKBM");
                string fieldValue_DKBM = pFeature.get_Value(fieldIndex_DKBM).ToString();

                // 报告进度
                bw.ReportProgress(pFeature.OID);
                pFeature = pFeatureCursor.NextFeature();
            }
        }

        // 显示进度
        private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            pgbReadStatus.Value = e.ProgressPercentage;
        }

        // 取消任务
        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.ToString());
                return;
            }
            if (e.Cancelled)
            {
                MessageBox.Show("终止");
            }
            else
            {
                MessageBox.Show("完成");
            }
        }

        // 获取要素类
        private IFeatureClass GetFeatureClass(string filePath)
        {
            IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
            IWorkspaceFactoryLockControl pWorkspaceFactoryLockControl = pWorkspaceFactory as IWorkspaceFactoryLockControl;
            if (pWorkspaceFactoryLockControl.SchemaLockingEnabled)
            {
                pWorkspaceFactoryLockControl.DisableSchemaLocking();
            }
            IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(filePath), 0);
            IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
            IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(System.IO.Path.GetFileName(filePath));
            return pFeatureClass;
        }

        // 开始
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (bw.IsBusy)
            {
                return;
            }
            bw.RunWorkerAsync();
        }

        // 取消
        private void btnCancel_Click(object sender, EventArgs e)
        {
            bw.CancelAsync();
        }

        // 关闭窗体
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            bw.CancelAsync();
        }
    }
}

加过如下:
当读取shp文件时,仍旧可以随意拖动窗体。在处理耗时操作时,可以考虑使用BackgroundWorker组件。

转载自:https://blog.csdn.net/HerryDong/article/details/86486557

You may also like...

退出移动版