因為要從DataTable中逐條檢查並導入大約10萬條紀錄到一個Sql表中。在此過程中,耗時較長,因此打算用一個Label來顯示導入紀錄的進度。以下為代碼:string PartNumber = ""; public void SetLabelText()
        {
                this.label2.Text = PartNumber;
                Thread.Sleep(100);
        }
private void btnCheckPartNumber_Click(object sender, EventArgs e)
        {
            foreach (DataRow dr in PNTable.Rows)
            {
                PartNumber = dr["PartNumber"].ToString();
                ThreadStart entryPoint = new ThreadStart(SetLabelText);
                Thread displayLabel = new Thread(entryPoint);
                displayLabel.Start();
             ----下面代碼為對dr紀錄進行對比檢查及更新
                if()
                   .......
            }
        }沒有達到期望的效果! 
謝謝!

解决方案 »

  1.   

    在数据更新显示的时候动态修改label的text数值。
    记得要label.doevent()
      

  2.   


    Thread.Sleep(100); 换成
    Application.DoEvents();
    就可以了。
      

  3.   

    多线程桌面应用(winform)程序中,如果非主线程要操作主线程的winform control,那么应该请看http://www.cnblogs.com/Caceolod/articles/1009004.html
      

  4.   

    剛才加了這句: Application.DoEvents();//实时响应对消息框的处理
    還是不行,第一次用多線程,大家幫忙看看是不是我寫的多線程代碼錯誤?
    謝謝
      

  5.   

    我用多線程的目的 是為了防止 Form 沒有反應,降低CPU 的使用率。這樣做可以達到期望的效果嗎?
      

  6.   

     string PartNumber = "";
            DataTable PNTable;
            delegate void SetValueEventHandler();
            public void SetLabelText()
            {
                if (this.label1.InvokeRequired)
                {
                    SetValueEventHandler de = SetLabelText;
                    label1.Invoke(de);
                   
                }
                foreach (DataRow dr in PNTable.Rows)
                {
                    PartNumber = dr["content"].ToString();
                    Application.DoEvents();
                    this.label1.Text = PartNumber;
                }            
            }
            private void btnCheckPartNumber_Click(object sender, EventArgs e) 
            {
                ThreadStart entryPoint = new ThreadStart(SetLabelText);
                Thread displayLabel = new Thread(entryPoint);
                displayLabel.Start();
            }
      

  7.   

    建议使用 System.ComponentModel.BackgroundWorker 类。
      

  8.   

    BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。注意 
    您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。
     如果后台操作需要参数,请在调用 RunWorkerAsync 时给出参数。在 DoWork 事件处理程序内部,可以从 DoWorkEventArgs.Argument 属性中提取该参数。
      

  9.   

    下面的代码示例演示如何在后台运行耗时的操作。该窗体具有“开始”和“取消”按钮。单击“开始”按钮可运行异步操作。单击“取消”按钮可停止正在运行的异步操作。每个操作的结果均在 MessageBox 中显示。using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;namespace BackgroundWorkerExample
    {
        public class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                // Do not access the form's BackgroundWorker reference directly.
                // Instead, use the reference provided by the sender parameter.
                BackgroundWorker bw = sender as BackgroundWorker;            // Extract the argument.
                int arg = (int)e.Argument;            // Start the time-consuming operation.
                e.Result = TimeConsumingOperation(bw, arg);            // If the operation was canceled by the user, 
                // set the DoWorkEventArgs.Cancel property to true.
                if (bw.CancellationPending)
                {
                    e.Cancel = true;
                }
            }        // This event handler demonstrates how to interpret 
            // the outcome of the asynchronous operation implemented
            // in the DoWork event handler.
            private void backgroundWorker1_RunWorkerCompleted(
                object sender, 
                RunWorkerCompletedEventArgs e)
            {   
                if (e.Cancelled)
                {
                    // The user canceled the operation.
                    MessageBox.Show("Operation was canceled");
                }
                else if (e.Error != null)
                {
                    // There was an error during the operation.
                    string msg = String.Format("An error occurred: {0}", e.Error.Message);
                    MessageBox.Show(msg);
                }
                else
                {
                    // The operation completed normally.
                    string msg = String.Format("Result = {0}", e.Result);
                    MessageBox.Show(msg);
                }
            }        // This method models an operation that may take a long time 
            // to run. It can be cancelled, it can raise an exception,
            // or it can exit normally and return a result. These outcomes
            // are chosen randomly.
            private int TimeConsumingOperation( 
                BackgroundWorker bw, 
                int sleepPeriod )
            {
                int result = 0;            Random rand = new Random();            while (!this.backgroundWorker1.CancellationPending)
                {
                    bool exit = false;                switch (rand.Next(3))
                    {
                        // Raise an exception.
                        case 0:
                        {
                            throw new Exception("An error condition occurred.");
                            break;
                        }                    // Sleep for the number of milliseconds
                        // specified by the sleepPeriod parameter.
                        case 1:
                        {
                            Thread.Sleep(sleepPeriod);
                            break;
                        }                    // Exit and return normally.
                        case 2:
                        {
                            result = 23;
                            exit = true;
                            break;
                        }                    default:
                        {
                            break;
                        }
                    }                if( exit )
                    {
                        break;
                    }
                }            return result;
            }        private void startBtn_Click(object sender, EventArgs e)
            {
                this.backgroundWorker1.RunWorkerAsync(2000);
            }        private void cancelBtn_Click(object sender, EventArgs e)
            {
                this.backgroundWorker1.CancelAsync();
            }        /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;        /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }        #region Windows Form Designer generated code        /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
                this.startBtn = new System.Windows.Forms.Button();
                this.cancelBtn = new System.Windows.Forms.Button();
                this.SuspendLayout();
                // 
                // backgroundWorker1
                // 
                this.backgroundWorker1.WorkerSupportsCancellation = true;
                this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
                this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
                // 
                // startBtn
                // 
                this.startBtn.Location = new System.Drawing.Point(12, 12);
                this.startBtn.Name = "startBtn";
                this.startBtn.Size = new System.Drawing.Size(75, 23);
                this.startBtn.TabIndex = 0;
                this.startBtn.Text = "Start";
                this.startBtn.Click += new System.EventHandler(this.startBtn_Click);
                // 
                // cancelBtn
                // 
                this.cancelBtn.Location = new System.Drawing.Point(94, 11);
                this.cancelBtn.Name = "cancelBtn";
                this.cancelBtn.Size = new System.Drawing.Size(75, 23);
                this.cancelBtn.TabIndex = 1;
                this.cancelBtn.Text = "Cancel";
                this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(183, 49);
                this.Controls.Add(this.cancelBtn);
                this.Controls.Add(this.startBtn);
                this.Name = "Form1";
                this.Text = "Form1";
                this.ResumeLayout(false);        }        #endregion        private System.ComponentModel.BackgroundWorker backgroundWorker1;
            private System.Windows.Forms.Button startBtn;
            private System.Windows.Forms.Button cancelBtn;
        }    public class Program
        {
            private Program()
            {
            }        /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.Run(new Form1());
            }
        }
    }
      

  10.   

    同意11楼,这种情景适合采用BackgroudWorker,我也做过类似的东西!当时我的情景是从将大量的数据保存到数据库中并保持
    用户界面的响应,progressbar动态显示进度
      

  11.   

    1、不开线程,直接在循环体中加Application.DoEvents()
    2、开线程,同步到主线程来显示进度,如何同步主线程,查SynchronizationContext类的使用
    其实方法一简单实用
      

  12.   

    下面的代码示例演示如何使用 BackgroundWorker 类异步执行耗时的操作。
    该操作计算选定的斐波纳契数,在计算过程中使用进度条报告进度更新,并允许取消挂起的计算。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);
            }        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);
            }        // 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;
            }未完,下面继续
      

  13.   

    续上        // 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());
            }
        }
    }