zoukankan      html  css  js  c++  java
  • BackgroundWorker在AE后台数据处理中的应用

    在AE数据处理过程中,数据量往往不小,单线程处理往往由于主线程阻滞导致用户就不能进行其他操作了,还会出现假死的状态。因此前端出现一个等待窗体或者进度条,在后台线程处理数据是很有必要的!

    今天计划实现这样的一个功能,使用BackgroundWorker来实现。首先还是要参考已有的例子!(水平低,没办法啊!)

    http://msdn.microsoft.com/zh-cn/library/b2zk6580(v=vs.85).aspx

    View Code
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;

    namespace BackgroundWorkerExample
    {
    public class FibonacciForm : System.Windows.Forms.Form
    {
    private int numberToCompute = 0;
    private int highestPercentageReached = 0;

    private System.Windows.Forms.NumericUpDown numericUpDown1;
    private System.Windows.Forms.Button startAsyncButton;
    private System.Windows.Forms.Button cancelAsyncButton;
    private System.Windows.Forms.ProgressBar progressBar1;
    private System.Windows.Forms.Label resultLabel;
    private System.ComponentModel.BackgroundWorker backgroundWorker1;

    public FibonacciForm()
    {
    InitializeComponent();

    InitializeBackgoundWorker();
    }

    // Set up the BackgroundWorker object by
    // attaching event handlers.
    private void InitializeBackgoundWorker()
    {
    backgroundWorker1.DoWork +=
    new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerCompleted +=
    new RunWorkerCompletedEventHandler(
    backgroundWorker1_RunWorkerCompleted);
    backgroundWorker1.ProgressChanged +=
    new ProgressChangedEventHandler(
    backgroundWorker1_ProgressChanged);
    }

    private void startAsyncButton_Click(System.Object sender,
    System.EventArgs e)
    {
    // Reset the text in the result label.
    resultLabel.Text = String.Empty;

    // Disable the UpDown control until
    // the asynchronous operation is done.
    this.numericUpDown1.Enabled = false;

    // Disable the Start button until
    // the asynchronous operation is done.
    this.startAsyncButton.Enabled = false;

    // Enable the Cancel button while
    // the asynchronous operation runs.
    this.cancelAsyncButton.Enabled = true;

    // Get the value from the UpDown control.
    numberToCompute = (int)numericUpDown1.Value;

    // Reset the variable for percentage tracking.
    highestPercentageReached = 0;

    // Start the asynchronous operation.
    backgroundWorker1.RunWorkerAsync(numberToCompute);//这里传入需要后台处理的数据参数numberToCompute
           //这句话很重要,我把DataTable导入ITable工作包装成一个类,在这句话之前将类的各个属性赋值,然后将该类作为参数传入
    }

    private void cancelAsyncButton_Click(System.Object sender,
    System.EventArgs e)
    {
    // Cancel the asynchronous operation.
    this.backgroundWorker1.CancelAsync();

    // Disable the Cancel button.
    cancelAsyncButton.Enabled = false;
    }

    // This event handler is where the actual,
    // potentially time-consuming work is done.
    private void backgroundWorker1_DoWork(object sender,
    DoWorkEventArgs e)
    {
    // Get the BackgroundWorker that raised this event.
    BackgroundWorker worker = sender as BackgroundWorker;

    // Assign the result of the computation
    // to the Result property of the DoWorkEventArgs
    // object. This is will be available to the
    // RunWorkerCompleted eventhandler.
    e.Result = ComputeFibonacci((int)e.Argument, worker, e);//这里通过e.Argument获取异步操作的参数数据,通过强制转换获得类对象,在该方法中实现功能。
    }

    // This event handler deals with the results of the
    // background operation.
    private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
    {
    // First, handle the case where an exception was thrown.
    if (e.Error != null)
    {
    MessageBox.Show(e.Error.Message);
    }
    else if (e.Cancelled)
    {
    // Next, handle the case where the user canceled
    // the operation.
    // Note that due to a race condition in
    // the DoWork event handler, the Cancelled
    // flag may not have been set, even though
    // CancelAsync was called.
    resultLabel.Text = "Canceled";
    }
    else
    {
    // Finally, handle the case where the operation
    // succeeded.
    resultLabel.Text = e.Result.ToString();
    }

    // Enable the UpDown control.
    this.numericUpDown1.Enabled = true;

    // Enable the Start button.
    startAsyncButton.Enabled = true;

    // Disable the Cancel button.
    cancelAsyncButton.Enabled = false;
    }

    // This event handler updates the progress bar.
    private void backgroundWorker1_ProgressChanged(object sender,
    ProgressChangedEventArgs e)
    {
    this.progressBar1.Value = e.ProgressPercentage;
    }

    // This is the method that does the actual work. For this
    // example, it computes a Fibonacci number and
    // reports progress as it does its work.实际后台运行的函数,负责计算斐波那契数列
    long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
    {
    // The parameter n must be >= 0 and <= 91.
    // Fib(n), with n > 91, overflows a long.
    if ((n < 0) || (n > 91))
    {
    throw new ArgumentException(
    "value must be >= 0 and <= 91", "n");
    }

    long result = 0;

    // Abort the operation if the user has canceled.
    // Note that a call to CancelAsync may have set
    // CancellationPending to true just after the
    // last invocation of this method exits, so this
    // code will not have the opportunity to set the
    // DoWorkEventArgs.Cancel flag to true. This means
    // that RunWorkerCompletedEventArgs.Cancelled will
    // not be set to true in your RunWorkerCompleted
    // event handler. This is a race condition.

    if (worker.CancellationPending)
    {
    e.Cancel = true;
    }
    else
    {
    if (n < 2)
    {
    result = 1;
    }
    else
    {
    result = ComputeFibonacci(n - 1, worker, e) +
    ComputeFibonacci(n - 2, worker, e);
    }

    // Report progress as a percentage of the total task.
    int percentComplete =
    (int)((float)n / (float)numberToCompute * 100);
    if (percentComplete > highestPercentageReached)
    {
    highestPercentageReached = percentComplete;
    worker.ReportProgress(percentComplete);
    }
    }

    return result;
    }


    #region Windows Form Designer generated code

    private void InitializeComponent()
    {
    this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
    this.startAsyncButton = new System.Windows.Forms.Button();
    this.cancelAsyncButton = new System.Windows.Forms.Button();
    this.resultLabel = new System.Windows.Forms.Label();
    this.progressBar1 = new System.Windows.Forms.ProgressBar();
    this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
    ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
    this.SuspendLayout();
    //
    // numericUpDown1
    //
    this.numericUpDown1.Location = new System.Drawing.Point(16, 16);
    this.numericUpDown1.Maximum = new System.Decimal(new int[] {
    91,
    0,
    0,
    0});
    this.numericUpDown1.Minimum = new System.Decimal(new int[] {
    1,
    0,
    0,
    0});
    this.numericUpDown1.Name = "numericUpDown1";
    this.numericUpDown1.Size = new System.Drawing.Size(80, 20);
    this.numericUpDown1.TabIndex = 0;
    this.numericUpDown1.Value = new System.Decimal(new int[] {
    1,
    0,
    0,
    0});
    //
    // startAsyncButton
    //
    this.startAsyncButton.Location = new System.Drawing.Point(16, 72);
    this.startAsyncButton.Name = "startAsyncButton";
    this.startAsyncButton.Size = new System.Drawing.Size(120, 23);
    this.startAsyncButton.TabIndex = 1;
    this.startAsyncButton.Text = "Start Async";
    this.startAsyncButton.Click += new System.EventHandler(this.startAsyncButton_Click);
    //
    // cancelAsyncButton
    //
    this.cancelAsyncButton.Enabled = false;
    this.cancelAsyncButton.Location = new System.Drawing.Point(153, 72);
    this.cancelAsyncButton.Name = "cancelAsyncButton";
    this.cancelAsyncButton.Size = new System.Drawing.Size(119, 23);
    this.cancelAsyncButton.TabIndex = 2;
    this.cancelAsyncButton.Text = "Cancel Async";
    this.cancelAsyncButton.Click += new System.EventHandler(this.cancelAsyncButton_Click);
    //
    // resultLabel
    //
    this.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
    this.resultLabel.Location = new System.Drawing.Point(112, 16);
    this.resultLabel.Name = "resultLabel";
    this.resultLabel.Size = new System.Drawing.Size(160, 23);
    this.resultLabel.TabIndex = 3;
    this.resultLabel.Text = "(no result)";
    this.resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
    //
    // progressBar1
    //
    this.progressBar1.Location = new System.Drawing.Point(18, 48);
    this.progressBar1.Name = "progressBar1";
    this.progressBar1.Size = new System.Drawing.Size(256, 8);
    this.progressBar1.Step = 2;
    this.progressBar1.TabIndex = 4;
    //
    // backgroundWorker1
    //
    this.backgroundWorker1.WorkerReportsProgress = true;
    this.backgroundWorker1.WorkerSupportsCancellation = true;
    //
    // FibonacciForm
    //
    this.ClientSize = new System.Drawing.Size(292, 118);
    this.Controls.Add(this.progressBar1);
    this.Controls.Add(this.resultLabel);
    this.Controls.Add(this.cancelAsyncButton);
    this.Controls.Add(this.startAsyncButton);
    this.Controls.Add(this.numericUpDown1);
    this.Name = "FibonacciForm";
    this.Text = "Fibonacci Calculator";
    ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
    this.ResumeLayout(false);

    }
    #endregion

    [STAThread]
    static void Main()
    {
    Application.Run(new FibonacciForm());
    }
    }
    }

    这段代码是微软MSDN中的一个计算斐波那契数列的例子,采用的是BackgroundWorker异步线程操作。这段代码可以直接保存运行,运行界面如下:

     

    这里分析的是如何实现AE数据处理中的应用,首先看看BackgroundWorker组件的属性和事件,加粗的就是经常会用到的。

    思路就是把DataTable数据转换到ITable所需的参数和方法包装成一个类DataTable2ITable,

    View Code
      1  class DataTable2ITable
    2 {
    3 private string columnX;
    4
    5 public string ColumnX
    6 {
    7 get { return columnX; }
    8 set { columnX = value; }
    9 }
    10 private string columnY;
    11
    12 public string ColumnY
    13 {
    14 get { return columnY; }
    15 set { columnY = value; }
    16 }
    17 private string iTablename;
    18
    19 public string ITablename
    20 {
    21 get { return iTablename; }
    22 set { iTablename = value; }
    23 }
    24 private DataTable dt;
    25
    26 public DataTable Dt
    27 {
    28 get { return dt; }
    29 set { dt = value; }
    30 }
    31 private string strWsp;
    32
    33 public string StrWsp
    34 {
    35 get { return strWsp; }
    36 set { strWsp = value; }
    37 }
    38 private ISpatialReference pSpatialReference;
    39
    40 public ISpatialReference SpatialReference
    41 {
    42 get { return pSpatialReference; }
    43 set { pSpatialReference = value; }
    44 }
    45 public IFeatureClass CreateFeatureTable()
    46 {
    47 IList<IFieldInfo> listFieldinfos = new List<IFieldInfo>();
    48 IFieldInfo m_OID=new OIDField();//OID字段
    49 listFieldinfos.Add(m_OID);
    50 IFieldInfo m_FieldGeo = new GeomtryField();
    51 IGeomtryInfo pGeoInfo = m_FieldGeo as IGeomtryInfo;
    52 pGeoInfo.GeometryType = esriGeometryType.esriGeometryPoint;
    53 pGeoInfo.HasZ = false;
    54 pGeoInfo.SpatialReference = pSpatialReference;
    55 listFieldinfos.Add(m_FieldGeo);
    56 foreach (DataColumn dc in dt.Columns)
    57 {
    58 IFieldInfo m_Holefield1 = new TableField();//表的其他字段
    59 switch (dc.DataType.Name)
    60 {
    61 case "String":
    62 m_Holefield1.Name_2 = dc.ColumnName;
    63 m_Holefield1.AliasName_2 = dc.Caption;
    64 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeString;
    65 m_Holefield1.Length_2 = dc.MaxLength;
    66 break;
    67 case "Single":
    68 m_Holefield1.Name_2 = dc.ColumnName;
    69 m_Holefield1.AliasName_2 = dc.Caption;
    70 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeSingle;
    71 m_Holefield1.Precision_2 = 2;
    72 break;
    73 case "Double":
    74 m_Holefield1.Name_2 = dc.ColumnName;
    75 m_Holefield1.AliasName_2 = dc.Caption;
    76 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeDouble;
    77 m_Holefield1.Precision_2 = 2;
    78 break;
    79 case "Int16":
    80 m_Holefield1.Name_2 = dc.ColumnName;
    81 m_Holefield1.AliasName_2 = dc.Caption;
    82 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
    83 m_Holefield1.Length_2 = 16;
    84 break;
    85 case "Int32":
    86 m_Holefield1.Name_2 = dc.ColumnName;
    87 m_Holefield1.AliasName_2 = dc.Caption;
    88 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
    89 m_Holefield1.Length_2 = 32;
    90 break;
    91 case "Int64":
    92 m_Holefield1.Name_2 = dc.ColumnName;
    93 m_Holefield1.AliasName_2 = dc.Caption;
    94 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeInteger;
    95 m_Holefield1.Length_2 = 64;
    96 break;
    97 default:
    98 m_Holefield1.Name_2 = dc.ColumnName;
    99 m_Holefield1.AliasName_2 = dc.Caption;
    100 m_Holefield1.Type_2 = esriFieldType.esriFieldTypeString;
    101 m_Holefield1.Length_2 = 255;
    102 break;
    103
    104 }
    105 listFieldinfos.Add(m_Holefield1);
    106 }
    107 GFieldsInfo m_fieldsinfo=new GFieldsInfo(listFieldinfos);
    108 IFields m_fields = m_fieldsinfo.CreateFieldsForTable();
    109 IFeatureClass m_featurecls= GCreateNewFeatureClass.CreateNewAccessFeatureClass(strWsp, iTablename, m_fields);
    110 return m_featurecls;
    111 //CloneDataTable(m_featurecls);
    112 }
    113 public void CloneDataRow(IFeatureClass m_featurecls,DataRow dr)
    114 {
    115 //foreach (DataRow dr in dt.Rows)
    116 //{
    117 IFeature m_feature = m_featurecls.CreateFeature();
    118 double x=Convert.ToDouble(dr[columnX]);
    119 double y=Convert.ToDouble(dr[columnY]);
    120 IPoint pt=new PointClass();
    121 pt.PutCoords(x,y);
    122 m_feature.Shape = pt as IGeometry;
    123 for (int i=0; i<dt.Columns.Count;i++)
    124 {
    125 int j=m_feature.Fields.FindField(dt.Columns[i].ColumnName);
    126 m_feature.set_Value(j, dr[i]);
    127 }
    128 m_feature.Store();
    129 //}
    130
    131 }

    DoWork事件和后台执行函数代码:

    View Code
     1  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    2 {
    3 BackgroundWorker worker = sender as BackgroundWorker;
    4 DataTable2ITable m_dt2IdtAsync = e.Argument as DataTable2ITable;
    5 e.Result = ComputeFibonacci(m_dt2IdtAsync, worker, e);
    6
    7 }
    8 int highestPercentageReached=0;
    9 long ComputeFibonacci(DataTable2ITable m_dt2IdtAsync, BackgroundWorker worker, DoWorkEventArgs e)
    10 {
    11 IFeatureClass pfeaturecls= m_dt2IdtAsync.CreateFeatureTable();
    12 int n = 0;
    13 foreach ( DataRow dr in m_Dt.Rows)
    14 {
    15 m_dt2IdtAsync.CloneDataRow(pfeaturecls, dr);
    16 n++;
    17 int percentComplete = (int)((float)n / (float)m_Dt.Rows.Count * 100);
    18 if (percentComplete > highestPercentageReached)
    19 {
    20 highestPercentageReached = percentComplete;
    21 worker.ReportProgress(percentComplete);
    22 }
    23 }
    24 return 100;
    25
    26 }

    运行界面:



    文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。 欢迎大家留言交流,转载请注明出处。
  • 相关阅读:
    设置Tomcat根目录
    使用Servlet Filter做Login checking
    Javac命令一次编译一个目录下的所有java文件
    Java ArrayList操作
    Java 读Properties
    Java文件读写
    Servlet Listener
    Servlet连接数据库
    Servlet Filter 3
    Servlet Filter 2
  • 原文地址:https://www.cnblogs.com/yhlx125/p/2399956.html
Copyright © 2011-2022 走看看