SQL查询填写backgroundworker后,数据表未显示信息 [英] Datatable not displaying information after SQL query fill in backgroundworker
问题描述
我正在用SQL查询中的数据填充DataTable
.因为它可能很慢,所以我正在运行查询,并使用BackgroundWorker
在DataTable
上进行了一些计算.我知道后台线程已运行,因为在RunWorkerCompleted
中,我设置了MessageBox
来显示消息.但是,一旦完成,DataTable
中将不会显示任何数据.
我知道这段代码有效,因为当我直接从按钮单击运行而不使用BackgroundWorker
时,我会在DataTable
中看到所有期望的数据. UI的更新和BackgroundWorker
可能是问题所在,因为我知道您不能直接从另一个线程更新UI,但老实说我不知道.我的代码在下面.
DataTable tab1table = new DataTable();
public Form1()
{
InitializeComponent();
Instantiatesearch1Thread();
}
private void Instantiatesearch1Thread()
{
search1Thread.WorkerReportsProgress = true;
search1Thread.WorkerSupportsCancellation = true;
search1Thread.ProgressChanged += search1Thread_ProgressChanged;
search1Thread.DoWork += search1Thread_Dowrk;
search1Thread.RunWorkerCompleted += search1Thread_RunWorkerCompleted;
}
private void sbutton1_Click(object sender, EventArgs e)
{
search1Thread.RunWorkerAsync();
}
void search1Thread_Dowrk(object sender, DoWorkEventArgs e)
{
int percentprogress = 0;
percentprogress++;
Thread.Sleep(1000);
// Search1 button event handler
using (SqlConnection conn = new SqlConnection(connectionstring))
{
conn.Open();
using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))
{
if (comboBox1.Text.Contains("ID"))
{
long para = long.Parse(search1.Text);
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = para,
SqlDbType = SqlDbType.BigInt
});
}
else if (comboBox1.Text.Contains("Other Thing") || comboBox1.Text.Contains("Other Stuff"))
{
string para = search1.Text;
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = "%" + para + "%",
SqlDbType = SqlDbType.NVarChar,
});
}
// Clear datatable if it contains any information and then fill it
// tab1datatable is a DataGridView
if (tab1table != null)
tab1table.Clear();
cmd.Fill(tab1table);
tab1datatable.DataSource = tab1table;
// A bunch of long calculations
}
}
}
void search1Thread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
search1Progress.Value = e.ProgressPercentage;
}
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("All Done!");
}
对于BackgroundWorker
,您必须稍作更改:
只需更新其中的DataTable
,然后在您的search1Thread_RunWorkerCompleted
上调用数据源更新过程即可,而不是更新BackgroundWorker
的search1Thread_Dowrk
中DataGridView
的DataSource
.
从此更改您的代码:
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("All Done!");
}
收件人:
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
tab1datatable.DataSource = tab1table;
tab1datatable.Refresh();
MessageBox.Show("All Done!");
}
I am filling a DataTable
with the data from a SQL query. As it can be quite slow, I am running the query and doing some computations on the DataTable
using BackgroundWorker
. I know the background thread has run because in RunWorkerCompleted
I have set a MessageBox
to display a message. Once complete, however, there is no data displayed in the DataTable
.
I know this code works, because when I run directly from the button click and not using BackgroundWorker
, I see all the expected data in the DataTable
. The issue is likely something with how the UI updates and the BackgroundWorker
, as I know you can't update the UI directly from another thread, but I honestly don't know. My code is below.
DataTable tab1table = new DataTable();
public Form1()
{
InitializeComponent();
Instantiatesearch1Thread();
}
private void Instantiatesearch1Thread()
{
search1Thread.WorkerReportsProgress = true;
search1Thread.WorkerSupportsCancellation = true;
search1Thread.ProgressChanged += search1Thread_ProgressChanged;
search1Thread.DoWork += search1Thread_Dowrk;
search1Thread.RunWorkerCompleted += search1Thread_RunWorkerCompleted;
}
private void sbutton1_Click(object sender, EventArgs e)
{
search1Thread.RunWorkerAsync();
}
void search1Thread_Dowrk(object sender, DoWorkEventArgs e)
{
int percentprogress = 0;
percentprogress++;
Thread.Sleep(1000);
// Search1 button event handler
using (SqlConnection conn = new SqlConnection(connectionstring))
{
conn.Open();
using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))
{
if (comboBox1.Text.Contains("ID"))
{
long para = long.Parse(search1.Text);
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = para,
SqlDbType = SqlDbType.BigInt
});
}
else if (comboBox1.Text.Contains("Other Thing") || comboBox1.Text.Contains("Other Stuff"))
{
string para = search1.Text;
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = "%" + para + "%",
SqlDbType = SqlDbType.NVarChar,
});
}
// Clear datatable if it contains any information and then fill it
// tab1datatable is a DataGridView
if (tab1table != null)
tab1table.Clear();
cmd.Fill(tab1table);
tab1datatable.DataSource = tab1table;
// A bunch of long calculations
}
}
}
void search1Thread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
search1Progress.Value = e.ProgressPercentage;
}
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("All Done!");
}
For the BackgroundWorker
you have to change your process a bit:
Instead of updating the DataSource
of the DataGridView
in the search1Thread_Dowrk
of BackgroundWorker
just update the DataTable
in it and then on your search1Thread_RunWorkerCompleted
call the DataSource updation process.
Change you code from this:
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("All Done!");
}
To:
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
tab1datatable.DataSource = tab1table;
tab1datatable.Refresh();
MessageBox.Show("All Done!");
}
这篇关于SQL查询填写backgroundworker后,数据表未显示信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!