我正在开发一个 .NET MAUI 应用程序,我需要从 JSON 文件加载大量数据并将其添加到 ObservableCollection。目前,应用程序在此操作期间变得无响应,并且过程很慢。
[ObservableProperty]private ObservableCollection<TaskMang> tasks;
private async Task LoadTasksFromExcel(){
var filepath = "C:\\Users\\USER\\Documents\\excel_to_json.json";
if (!File.Exists(filepath))
{
return;
}
var stopwatch = new Stopwatch();
stopwatch.Start();
try
{
var jsonString = await File.ReadAllTextAsync(filepath);
var jsonDocument = JsonDocument.Parse(jsonString);
var root = jsonDocument.RootElement;
if (root.TryGetProperty("Task_Master", out JsonElement taskArray))
{
// Use IEnumerable for lazy loading
var tasksEnumerable = taskArray.EnumerateArray().Select(task => new TaskMang
{
id = task.GetProperty("TASK_ID").GetInt32(),
TaskName = task.GetProperty("TASK_NAME").GetString(),
TaskStartTime = task.GetProperty("START_TIME").GetString(),
TaskEndTime = task.GetProperty("END_TIME").GetString(),
TaskTimeTaken = task.GetProperty("TIME_TAKEN").GetString(),
ProjectName = task.GetProperty("PROJECT_NAME").GetString(),
SelectedProject = _projectDetailsViewModel.Projects
.FirstOrDefault(p => p.ProjectName == task.GetProperty("PROJECT_NAME").GetString())
}).ToList();
// Add tasks to ObservableCollection in smaller batches
const int batchSize = 100;
for (int i = 0; i < tasksEnumerable.Count; i += batchSize)
{
var batch = tasksEnumerable.Skip(i).Take(batchSize).ToList();
Application.Current.Dispatcher.Dispatch(() =>
{
foreach (var task in batch)
{
Tasks.Add(task);
}
});
await Task.Delay(10); // Small delay to prevent UI freeze
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
stopwatch.Stop();
Console.WriteLine($"Time taken: {stopwatch.ElapsedMilliseconds} ms");
}}
性能:应用程序在数据加载期间变得无响应。 UI 冻结:即使进行批处理和较小的延迟,UI 仍然会冻结。
我尝试过: 批量更新:延迟小批量添加项目。 延迟加载:使用 IEnumerable 处理数据
问题: 是否有更有效的方法来处理 ObservableCollection 中的大型数据集? 添加大量项目时是否有更好的方法来避免 UI 冻结? 在 .NET MAUI 中优化 JSON 数据处理有什么建议吗?
您所需要的就是使用
ObservableRangeCollection
并且有一个名为 AddRange
的方法。您可以在这里找到这样的集合https://github.com/MPowerKit/VirtualizeListView/blob/main/MPowerKit.VirtualizeListView/ObservableRangeCollection.cs
注意:在幕后
ObservableCollection
,因此ObservableRangeCollection
将项目存储在List<T>
中,因此不需要进行批量更新,更重要的是,批处理只会降低你的性能。
我要做的 - 是在后台线程中解析 json,然后在主线程中的集合上调用
AddRange
。
但您还必须记住哪些 UI 元素正在使用该集合。如果是
BindableLayout
,那么在那里使用庞大的数据集是不可接受的。
在获取和解析数据之前,我会向用户展示一些加载器,让他可以理解现在正在发生什么,他应该稍等一下。