[英]C# Update DataGridView from BackgroundWorker
仍在努力將實時數據從我的數據庫獲取到datagridview。 這次,我嘗試通過后台工作人員執行此操作。 它從doWork方法提供的唯一內容是backgroundWorker1_ProgressChanged方法的INT。 我也想向其發送諸如DataTable之類的對象,因此我可以刷新主線程Form1上的數據。 如何將對象傳遞給backgroundWorker1_ProgressChanged事件? 在代碼中標記了我需要來自DoWork的數據的位置
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string IP_db_mysql = "1";
string Port_db__mysql = "1";
string UserName_db__mysql = "1";
string Password_db__mysql = "1";
string dbName__mysql = "1";
string connString = "Server =" + IP_db_mysql + "; Port =" + Port_db__mysql + "; Database =" + dbName__mysql + "; Uid =" + UserName_db__mysql + ";Pwd =" + Password_db__mysql + ";";
MySqlConnection conn = new MySqlConnection();
DataTable dt = new DataTable();
string query = "SELECT * FROM mysql.test_table;";
int sum = 0;
for (int i = 1; i <= 10; i++)
{
sum = sum + i;
try
{
// open connectipon
conn.ConnectionString = connString;
conn.Open();
// build command
MySqlCommand cmd = new MySqlCommand(query, conn);
// execute command
MySqlDataReader dataReader = cmd.ExecuteReader();
// fill datatable
dt.Load(dataReader);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
// Calling ReportProgress() method raises ProgressChanged event
// To this method pass the percentage of processing that is complete
backgroundWorker1.ReportProgress(i);
Thread.Sleep(100);
// Check if the cancellation is requested
if (backgroundWorker1.CancellationPending)
{
// Set Cancel property of DoWorkEventArgs object to true
e.Cancel = true;
// Reset progress percentage to ZERO and return
backgroundWorker1.ReportProgress(0);
return;
}
}
// Store the result in Result property of DoWorkEventArgs object
e.Result = sum;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
labelProgress.Text = e.ProgressPercentage.ToString() + "%";
**----------->> dataGridView1.DataSource = HOW TO GET DATATABLE FROM DO WORK METHOD !? <<------------------------**
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
labelProgress.Text = "Processing cancelled";
}
else if (e.Error != null)
{
labelProgress.Text = e.Error.Message;
}
else
{
labelProgress.Text = e.Result.ToString();
}
}
private void button23_Click(object sender, EventArgs e)
{
// Check if the backgroundWorker is already busy running the asynchronous operation
if (!backgroundWorker1.IsBusy)
{
// This method will start the execution asynchronously in the background
backgroundWorker1.RunWorkerAsync();
}
}
private void button24_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy)
{
// Cancel the asynchronous operation if still in progress
backgroundWorker1.CancelAsync();
}
}
使用下面的代碼之類的狀態對象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Data;
namespace ConsoleApplication76
{
class Program
{
static void Main(string[] args)
{
}
}
public enum ReportTypes
{
PROGRESS,
DATATABLE
}
public class Report
{
public int progress { get; set; }
public ReportTypes type { get; set; }
public DataTable table { get; set; }
}
public class Worker
{
public BackgroundWorker backgroundWorker1 { get; set; }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Report report = new Report();
report.progress = 50;
report.type = ReportTypes.PROGRESS;
backgroundWorker1.ReportProgress(50, report);
DataTable dt = new DataTable();
report.table = dt;
report.type = ReportTypes.DATATABLE;
backgroundWorker1.ReportProgress(50, report);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int progress = e.ProgressPercentage;
Report report = e.UserState as Report;
switch (report.type)
{
case ReportTypes.PROGRESS :
BeginInvoke((MethodInvoker)delegate
{
WriteStatusAndError("Query Completed");
});
break;
case ReportTypes.DATATABLE :
break;
}
}
}
}
在BackgroundWorker的DoWork
結束時,您需要將其DataSource
設置為結果。 但是,由於您直接在后台工作,因此您將獲得異常,因為WinForms不允許您從另一個線程訪問UI。
您可以使用以下代碼執行此操作:
// create a method to handle updating the datasource
public void UpdateDataGridViewSource(object data)
{
// check if we need to swap thread context
if(this.dataGridView1.InvokeRequired)
{
// we aren't on the UI thread. Ask the UI thread to do stuff.
this.dataGridView1.Invoke(new Action(() => UpdateDataGridViewSource(data)));
}
else
{
// we are on the UI thread. We are free to touch things.
this.dataGridView1.DataSource = data;
this.dataGridView1.DataBind();
}
}
// at the end of your DoWork()
this.UpdateDataGridViewSource(result);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.