因為要從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()
.......
}
}沒有達到期望的效果!
謝謝!
{
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()
.......
}
}沒有達到期望的效果!
謝謝!
记得要label.doevent()
Thread.Sleep(100); 换成
Application.DoEvents();
就可以了。
還是不行,第一次用多線程,大家幫忙看看是不是我寫的多線程代碼錯誤?
謝謝
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();
}
您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。 如果后台操作需要参数,请在调用 RunWorkerAsync 时给出参数。在 DoWork 事件处理程序内部,可以从 DoWorkEventArgs.Argument 属性中提取该参数。
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());
}
}
}
用户界面的响应,progressbar动态显示进度
2、开线程,同步到主线程来显示进度,如何同步主线程,查SynchronizationContext类的使用
其实方法一简单实用
该操作计算选定的斐波纳契数,在计算过程中使用进度条报告进度更新,并允许取消挂起的计算。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;
}未完,下面继续
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());
}
}
}