gpt4 book ai didi

c# - 将预计算与延迟加载混合

转载 作者:太空宇宙 更新时间:2023-11-03 11:12:04 25 4
gpt4 key购买 nike

我有一个包含许多部分的应用程序,每个部分都包含需要花费大量时间来计算的数据。我可以看到一些方法:

  1. 简单解决方案 1:计算应用程序启动时所有部分的数据。这意味着应用程序启动会很慢。

  2. 简单的解决方案 2:在用户加载数据时计算每个部分中的数据。这意味着加载每个部分会很慢(这很糟糕,因为每个部分都已经进行了大量的渲染计算,所以它们已经有点慢了。

  3. 由于性能对于此应用程序至关重要,因此这些解决方案都不是理想的。所以这给我带来了一个不太简单的解决方案:在应用程序启动时,开始在后台线程上计算部分数据。这个解决方案的问题是我没有一个好的方法来预测用户将首先加载哪个部分。因此,如果他们加载最后一部分以在后台线程上加载,他们最终等待的时间将比我刚刚采用解决方案 2 时要长。

  4. 所以这让我想到了解决方案:在应用程序启动时,开始在后台线程上计算部分数据,但是当用户加载一个部分时,暂停后台线程并开始计算用户请求的部分。 除非计算已经开始,在这种情况下您让它完成。

我不确定如何实现解决方案 4。我认为最简单的解决方案可能是使用优先级队列并在加载任务时提高任务的优先级,但我不确定如何在 C# 中实现它.这是一个合理的方法吗? C#中优先级队列有哪些好的库?

最佳答案

所以我们将从 Task<Section> 的数组(或其他一些数据结构,如果需要的话)开始对象。

private Task<Section>[] sections = new Task<Section>[5];

您应该确保在应用程序一开始就创建了集合并实际定义了任务(而不是在后台)。

for (int i = 0; i < sections.Length; i++)
{
int sectionNumber = i; //copy for closure
Task<Section> next = new Task<Section>(() => CreateSection(sectionNumber));
//note the task isn't started.
sections[i] = next;
}

然后你可以启动后台任务来实际处理一个任务:

Task.Run(() =>
{
for (int i = 0; i < sections.Length; i++)
{
EnsureStarted(sections[i]);
sections[i].Wait();
}
});

你可以使用 Parallel.For如果你想让多个线程处理项目。

该方法使用此辅助方法:

public void EnsureStarted(Task task)
{
if (task.Status == TaskStatus.Created)
{
task.Start();
}
}

然后实际得到一个完成的部分(如果需要就开始):

public Section GetFinishedSection(int sectionNumber)
{
EnsureStarted(sections[sectionNumber]);
return sections[sectionNumber].Result;
}

如果你需要它的非阻塞版本(可能是 await 它)你可以使用这个:

public Task<Section> EnsureSectionComplete(int sectionNumber)
{
EnsureStarted(sections[sectionNumber]);
return sections[sectionNumber];
}

关于c# - 将预计算与延迟加载混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13651737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com