I have an application that provides users with the option to select a SQL table to view from a list of tables. I instantiate a second wpf window that renders the table's fields in a grid. Everything works well, however, for larger tables, I want to update a StatusBar TextBlock to show the row-count as a datatable is filled asynchronously. I try to do this by monitoring the dataTable.Count property as the datatable is loaded by a task.
I instantiate the second window from this event handler.
private void OnItem_DoubleClick(object sender, RoutedEventArgs e)
{
var selected = DataViewsListBox.SelectedItem.ToString();
var tableLoadWindowThread = new Thread(() =>
{
var tableWindow = new TableWindow();
tableWindow.Show();
tableWindow.LoadDataView(selected);
System.Windows.Threading.Dispatcher.Run();
});
tableLoadWindowThread.SetApartmentState(ApartmentState.STA);
tableLoadWindowThread.IsBackground = true;
tableLoadWindowThread.Start();
}
I load a grid in the second window using this code. I am also attempting to update the StatusBar TextBlock.Text field with the count of datatable rows added in during the while loop --
public void LoadDataView(string dataView)
{
var dataTable = new DataTable();
var t = Task.Factory.StartNew(() =>
{
using (var adapter = new SqlDataAdapter(@"select * from " + dataView, @"conn string"))
{
adapter.Fill(dataTable);
}
});
while (!t.IsCompleted)
{
if (!StatusText.Dispatcher.CheckAccess())
{
StatusText.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate() { StatusText.Text = "Loading data source, row count = " + dataTable.Rows.Count; }));
}
else
{
StatusText.Text = "Loading data source, row count = " + dataTable.Rows.Count;
}
}
TableGridView.ItemsSource = dataTable.AsEnumerable().ToList();
StatusText.Text = dataTable.Rows.Count + " data source rows loaded.";
}
The second window renders, it is blocked, and the StatusText.Text field is not updated. The debugger shows that the while loop is updating the StatusText.Text field, as expected. The window does not render the filled grid, or StatusBar/TextBlock, Dispatcher.Run() statement.
The method for monitoring the load of the datatable asynchronously works well outside the context of a wpf application. I am hoping her for some coaching on how wpf's threading, task, dispatcher model works in order to fix this code. Thanks.