无论是在加载时间还是在UI的死锁方面,我在TreeView上都有一个主要的性能问题。
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;
}
此函数在OnNavigatedTo中首次被调用:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await LoadTreeAsync();
}
它在不到一秒钟的时间内运行。我有4个AppBarButtons来选择排序状态。在他们的方法中:
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();
}
它陷入僵局,持续了10秒钟以上。我不明白为什么以及如何解决。我已经检查过,查询没有影响,无论如何它们都将在几毫秒内执行。
我不太喜欢这种方法,因为它会破坏并重新创建所有对象。因此,我什至尝试更改它,以便如果Patient不为null而不是销毁并重新创建,则使用LINQ对现有对象进行排序:
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;
[我在Clear上有大约1秒的死锁,在Patients = _Patients;
上有10秒或更长时间的第二个死锁
我做错了什么?为什么从首次通话到所有其他通话有如此大的差异?
而且我在Clear上有大约1秒的死锁,还有第二个10秒的死锁。
LoadTreeAsync
方法没有任务重运行值。因此,我们不需要使Task返回方法,请用void替换Task。我发现LoadTreeAsync
方法中有很多UI交互,请确保使用Dispatcher
在UI线程中调用它们。
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;
});
}