仍然努力将实时数据从我的数据库获取到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();
}
}
答案 0 :(得分:1)
使用下面的代码之类的状态对象
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;
}
}
}
}
答案 1 :(得分:1)
在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);