Reputation: 1
When I use a delegate method to run my method in order to let the UI refresh, the UI does not refresh. I want stop the UI from freezing while the method runs, what can I do?
private void SearchToolStripButton_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(StartMethod));
t.Start();
}
private delegate void InvokeDelegate();
public void StartMethod()
{
this.BeginInvoke(new InvokeDelegate(SearchData));
}
public void SearchData()
{
if (searchKeywordTextBox.Text == "")
{
MessageBox.Show("Please type the keyword!");
}
else
{
if (searchDateTimePicker.Checked == true)
{
switch (selectRangeComboBox.Text)
{
case "Day": showDataToresultDataGridViewOnDay(searchKeywordTextBox.Text);
break;
case "Month": showDataToresultDataGridViewInMonth(searchKeywordTextBox.Text);
break;
case "Year": showDataToresultDataGridViewInYear(searchKeywordTextBox.Text);
break;
default: MessageBox.Show("Please select a Section");
break;
}
}
else
{
showDataToresultDataGridView(searchKeywordTextBox.Text);
}
}
}
public void showDataToresultDataGridViewOnDay(string keyword)
{
DataGridView dayGrid = resultDataGridView;
ShowResultDay day = new ShowResultDay();
resultDataGridView.DataSource = day.ShowGridDay(searchDateTimePicker.Value.Day, searchDateTimePicker.Value.Month, searchDateTimePicker.Value.Year, keyword);
resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Day + "/" + searchDateTimePicker.Value.Month + "/" + searchDateTimePicker.Value.Year;
}
public void showDataToresultDataGridViewInMonth(string keyword)
{
DataGridView monthGrid = resultDataGridView;
ShowResultMonth month = new ShowResultMonth();
resultDataGridView.DataSource = month.ShowGridMonth(searchDateTimePicker.Value.Month, searchDateTimePicker.Value.Year, keyword);
resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Month + "/" + searchDateTimePicker.Value.Year;
}
public void showDataToresultDataGridViewInYear(string keyword)
{
DataGridView yearGrid = resultDataGridView;
ShowResultYear year = new ShowResultYear();
resultDataGridView.DataSource = year.ShowGridYear(searchDateTimePicker.Value.Year, keyword);
resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records in " + searchDateTimePicker.Value.Year;
}
public void showDataToresultDataGridView(string keyword)
{
ShowAllData all = new ShowAllData();
var results = all.ShowGirdAll(keyword);
resultDataGridView.DataSource = results;
resultLabel.Text = "Showing " + resultDataGridView.RowCount + " records";
}
Upvotes: 0
Views: 397
Reputation: 57220
You should have a look at BackgroundWorker
class, that has been implemented expressly to make multi-threading easier in WinForms.
Then I'd suggest another thing:
don't open the messageboxes from the the background thread, but check properties and fields before to start the thread, and then run only the search in the non-ui thread.
Example of background worker usage:
// Initialization
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
// Start elaboration
bw.RunWorkerAsync(objectArgument);
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// do your work (we are in the background-thread)
// when you have finished, set your results in the e.Result property
// N.B. don't show anything because we are in the background-thread
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// here we have finished the work (we are in the UI-thread)
// result is set in e.Result property
// N.B. check e.Error property before to get e.Result because
// if there's an error e.Result throws an exception
}
Upvotes: 3
Reputation: 1
Unlike Native Win32 API or MFC , Dot-net framework doesn't support multithreaded UI method's *calls for control's . Thus you can't create UI control (window) in any thread and call it's method and set property from another one ! (*here and below - UI method's that updates (refreshes) UI context . You can read data from control and can't write to) By the way , in the native environment such calls don't work reliably too, sometimes throwing badly managed exception ... But managed environment can not allow the method call would cause an exception at all ! It just 'freezes' a such call and do nothing to refresh . Incidentally, this feature of the platform is not only for background threads . Whether calling BeginInvoke (from the built-in thread pool), or creating a user's non-background thread by another way you'll get the same problem . In your specific case I cannot see any reason to have two or more threads share the same control - it is also dangerous in terms of data safety . Typically, other threads (and generally parallelism) are used for entirely different purposes: for any long time computing , I/O operations of databases , files, network. Although, of course, you can invoke some Message Boxes in other thread .
Upvotes: 0