Я прочитал оба BackgroundWorker по-прежнему замораживает пользовательский интерфейс и Пользовательский интерфейс по-прежнему замораживается с помощью backgroundWorker , но ни один из них не помог мне решить мою проблему. Несколько дней назад я задал вопрос о том, что Datatable не отображает информацию после заполнения SQL-запроса в backgroundworker , что я в итоге решил, используя Invoke
и delegate
.
Мой текущий код (показанный ниже) дает мне результаты, которые я хочу, за исключением двух вещей: на самом деле он не отображает индикатор выполнения (по крайней мере, что я вижу) и останавливает интерфейс во время работы:
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;
var worker = sender as BackgroundWorker;
// Ensure process is thread-safe by using Invoke method
Invoke(new MethodInvoker(delegate
{
// Search1 button event handler
using (SqlConnection conn = new SqlConnection(Connection_Info))
{
conn.Open();
using (SqlDataAdapter cmd = new SqlDataAdapter(comboBox1SQL, conn))
{
//MessageBox.Show("Working");
if (comboBox1.Text.Contains("ID"))
{
long para = long.Parse(search1.Text);
cmd.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "@combo1Par",
Value = para,
SqlDbType = SqlDbType.BigInt
});
}
// Clear datatable if it contains any information and then fill it
if (tab1table != null)
tab1table.Clear();
cmd.Fill(tab1table);
// Set Progress Bar info
search1Progress.Maximum = tab1table.Rows.Count;
groupBox2.Controls.Add(search1Progress);
search1Progress.BringToFront();
}
}
// This is a long calculation where I am reporting the
// progress every iteration (which is probably not helping,
// but didn't change anything when commented out).
if(!String.IsNullOrEmpty(search1.Text) && tab1Combo1.SelectedIndex > -1 || tab1Combo2.SelectedIndex > -1)
{
for (int i = tab1table.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = tab1table.Rows[i];
if (!dr.ItemArray.Contains(search1.Text.ToString()))
{
dr.Delete();
tab1table.AcceptChanges();
}
percentprogress++;
worker.ReportProgress(percentprogress);
}
}
}));
}
void search1Thread_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
search1Progress.Value = e.ProgressPercentage;
}
void search1Thread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
tab1datatable.DataSource = null;
tab1datatable.DataSource = tab1table;
tab1datatable.Update();
groupBox2.Controls.Remove(search1Progress);
MessageBox.Show(" Your search returned " + tab1table.Rows.Count.ToString() + " results");
}
Кто-нибудь может указать, что я здесь делаю неправильно?
Моя проблема может иметь отношение к Invoke
, так как я знаю, что это не самый лучший метод с BackgroundWorker
, но я не смог заставить его обновить пользовательский интерфейс любым другим методом.