I've read a Stephen Cleary's article that it is necessary to explicitly set from TaskScheduler.Current
to TaskScheduler.Default
.
When my program is started, then loading of data begins. It takes approximately 5 seconds. If I click at the button Add while loading data, then new window will not be opened till Task
operation of method ReadData()
is not completed.
ViewModel:
public class MainWindowVM:ViewModelBase
{
public MainWindowVM()
{
AddPersonCommand = new RelayCommand<object>(AddPerson);
ReadData();
}
private void ReadData()
{
PersonData = new ObservableCollection<PersonDepBureau>();
IList<PersonDepBureau> persons;
Task.Factory.StartNew(() =>
{
using (PersonDBEntities db = new PersonDBEntities())
{
persons = (from pers in db.Person
join bu in db.Bureau on pers.Fk_IdBureau equals bu.IdBureau
join dep in db.Departament on pers.Fk_IdDep equals dep.IdDep
select new PersonDepBureau
{
IdPerson = pers.IdPerson,
PersonName = pers.Name,
Surname = pers.Surname,
).ToList();
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
foreach (var person in persons)
{
PersonData.Add(person);
}
}));
}
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
}
//Opening new Window AddPersonWindow.xaml
private void AddPerson(object obj)
{
AddPersonWindow addPersonWindow = new AddPersonWindow();
addPersonWindow.DataContext new AddPersonVM();
addPersonWindow.ShowDialog();
}
}
View:
<extToolkit:BusyIndicator IsBusy="{Binding IsBusy}" Foreground="Black">
<DataGrid ItemsSource="{Binding PersonData}" SelectedItem="{Binding SelectedPerson}"
IsSynchronizedWithCurrentItem="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding PersonName}"/>
<DataGridTextColumn Header="Surname" Binding="{Binding Surname}" />
</DataGrid.Columns>
</DataGrid>
</extToolkit:BusyIndicator>
<Grid Grid.Row="1">
<Button Command="{Binding AddPersonCommand}" Margin="5" Grid.Column="1">Add</Button>
</Grid>
Cannot use async/await
syntactic sugars as my application can be used in Windows XP(I cannot ask users to install .NET 4.5
). Thank in advance.
It is really weird behaviour. All info that I've read about is using Task
like I did. But my example is not working properly(new window is not opened while loading data), so to show an error behavior I've made a test application and it can be downloaded here.. Cause I've heard a lot of comments to use TaslScheduler.Default
.
Please, do not close my thread as it is really important to me to understand the reason why my UI is unresponsive.
Stephen Cleary's article is perfect. Thanks for patience to Peter Bons.
The construction Task.Factory.StartNew(() =>}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
is perfectly works, the reason of freezing UI is another operation executed on UI thread.