问题
I have a major performance issue on a TreeView both in terms of loading time as well as a deadlock of the UI.
private async Task LoadTreeAsync()
{
List<VPazVisit> aList = new List<VPazVisit>();
if (_sorting == "")
{
_sorting = await ApplicationData.Current.LocalSettings.ReadAsync<string>("TreeViewSort");
}
treeView.Visibility = Visibility.Collapsed;
Patients.Clear();
switch (_sorting)
{
default:
case "DescDate":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderByDescending(b => b.Data).ThenBy(b => b.Cognome).ThenBy(b => b.Nome)
.ToList());
break;
case "AsceDate":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderBy(b => b.Data).ThenBy(b => b.Cognome).ThenBy(b => b.Nome)
.ToList());
break;
case "DescAlph":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderByDescending(b => b.Cognome).ThenByDescending(b => b.Nome).ThenBy(b => b.Data)
.ToList());
break;
case "AsceAlph":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderBy(b => b.Cognome).ThenBy(b => b.Nome).ThenBy(b => b.Data)
.ToList());
break;
}
try
{
foreach (var item in aList)
{
MTreeViewPaz aMTree = new MTreeViewPaz(item);
Patients.Add(aMTree);
}
}
catch (Exception e)
{
}
treeView.Visibility = Visibility.Visible;
return;
}
This function is called the first time in OnNavigatedTo:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await LoadTreeAsync();
}
It runs in less than a second. I have a 4 AppBarButtons to select the sorting state. In their method:
private async void AppBarToggleButton_Checked(object sender, RoutedEventArgs e)
{
string sorting = await ApplicationData.Current.LocalSettings.ReadAsync<string>("TreeViewSort");
switch (((Windows.UI.Xaml.Controls.AppBarToggleButton)sender).Name)
{
case "DescDate":
if (sorting == "DescDate")
{
return;
}
AsceDate.IsChecked = false;
AsceAlph.IsChecked = false;
DescAlph.IsChecked = false;
break;
case "AsceDate":
if (sorting == "AsceDate")
{
return;
}
DescDate.IsChecked = false;
AsceAlph.IsChecked = false;
DescAlph.IsChecked = false;
break;
case "DescAlph":
if (sorting == "DescAlph")
{
return;
}
AsceDate.IsChecked = false;
DescDate.IsChecked = false;
AsceAlph.IsChecked = false;
break;
case "AsceAlph":
if (sorting == "AsceAlph")
{
return;
}
AsceDate.IsChecked = false;
DescDate.IsChecked = false;
DescAlph.IsChecked = false;
break;
default:
break;
}
await ApplicationData.Current.LocalSettings.SaveAsync("TreeViewSort", ((Windows.UI.Xaml.Controls.AppBarToggleButton)sender).Name);
_sorting = ((Windows.UI.Xaml.Controls.AppBarToggleButton)sender).Name;
await LoadTreeAsync();
}
It deadlocks he interface for more than 10 sec. I cannot understand why and how to solve it. I've checked and the queries are NOT impacting, they are executed in any case in few milliseconds.
I do not like this method a lot as it destroys and re creates all the oobjects. So I've even tried to change it so that if Patients is not null instead of destroying and re creating I use LINQ to sort the existing objects:
treeView.Visibility = Visibility.Collapsed;
_Patients= new ObservableCollection<MTreeViewPaz>(
from i in Patients orderby i.Data descending, i.Cognome, i.Nome select i);
await treeView.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal ,()=>
{
Patients.Clear();
Patients = _Patients;
});
treeView.Visibility = Visibility.Visible;
And I have a deadlock around 1 sec on the Clear and a second deadlock of 10 sec or more on the Patients = _Patients;
What am I doing wrong? why this massive difference from the first call to all other ones?
回答1:
And I have a deadlock around 1 sec on the Clear and a second deadlock of 10 sec.
LoadTreeAsync
method has no task retrun value. So, we have no need make Task return method, please replace Task with void. I found there are many UI interactions in LoadTreeAsync
mthod, please make sure that call them in UI-thread with Dispatcher
.
private async void LoadTreeAsync()
{
List<VPazVisit> aList = new List<VPazVisit>();
if (_sorting == "")
{
_sorting = await ApplicationData.Current.LocalSettings.ReadAsync<string>("TreeViewSort");
}
treeView.Visibility = Visibility.Collapsed;
Patients.Clear();
switch (_sorting)
{
default:
case "DescDate":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderByDescending(b => b.Data).ThenBy(b => b.Cognome).ThenBy(b => b.Nome)
.ToList());
break;
case "AsceDate":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderBy(b => b.Data).ThenBy(b => b.Cognome).ThenBy(b => b.Nome)
.ToList());
break;
case "DescAlph":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderByDescending(b => b.Cognome).ThenByDescending(b => b.Nome).ThenBy(b => b.Data)
.ToList());
break;
case "AsceAlph":
aList = await Task.Run(() => App.gDataContext.Cache.VPazVisit
.OrderBy(b => b.Cognome).ThenBy(b => b.Nome).ThenBy(b => b.Data)
.ToList());
break;
}
try
{
foreach (var item in aList)
{
MTreeViewPaz aMTree = new MTreeViewPaz(item);
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
Patients.Add(aMTree);
});
}
}
catch (Exception e)
{
}
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
treeView.Visibility = Visibility.Visible;
});
}
来源:https://stackoverflow.com/questions/61328545/uwp-treeview-ui-deadlock-loading-time-from-less-than-1-sec-to-more-than-10-sec