2

多数のセクションを含むアプリケーションがあり、それぞれに計算にかなりの時間がかかるデータが含まれています。これにはいくつかのアプローチがあります。

  1. 簡単な解決策 1: アプリケーションの起動時にすべてのセクションのデータを計算します。これは、アプリケーションの起動が遅くなることを意味します。

  2. 簡単な解決策 2: ユーザーがロードするときに各セクションのデータを計算します。これは、各セクションのロードが遅くなることを意味します (これは悪いことです。なぜなら、各セクションはすでにかなりのレンダリング計算を行う必要があるため、すでに少し遅いからです.

  3. このアプリケーションではパフォーマンスが重要であるため、これらのソリューションはどちらも理想的ではありません。したがって、これは単純ではない解決策につながります。アプリの起動時に、バックグラウンド スレッドでセクション データの計算を開始します。このソリューションの問題は、ユーザーが最初にロードするセクションを予測する良い方法がないことです。そのため、バックグラウンド スレッドにロードする最後のセクションをロードすると、解決策 2 を使用した場合よりも長く待機することになります。

  4. したがって、これは解決策につながります。アプリの起動時に、バックグラウンド スレッドでセクション データの計算を開始しますが、ユーザーがセクションをロードすると、バックグラウンド スレッドを一時停止し、ユーザーが要求したセクションの計算を開始します。計算がすでに開始されていない限り、その場合は終了させます。

解決策 4 を実装する方法がわかりません。おそらく最も簡単な解決策は、プライオリティ キューを使用し、タスクがロードされたときにタスクの優先度を上げることだと思いますが、C# でこれを実装する方法がわかりません。これは合理的なアプローチですか?C# のプライオリティ キューに適したライブラリは何ですか?

4

2 に答える 2

1

ソリューション 4 の変更として、バックグラウンドで各セクションの読み込みを開始できます。ユーザーがセクションを選択したら、現在プライマリ スレッド キューによってロードされているかどうかを確認し、そうでない場合は、新しいスレッドをスピンオフして、そのセクションをより高い優先度でロードします。もちろん、この選択をプライマリ タスク キューから削除する必要があります。

MSDN から優先度を設定する例を次に示します。

于 2012-11-30T19:36:12.973 に答える
1

したがって、オブジェクトの配列 (または必要に応じて他のデータ構造) から始め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;
}

次に、バックグラウンド タスクを開始して、一度に 1 つずつタスクを実際に処理できます。

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

Parallel.For複数のスレッドでアイテムを処理したい場合は、 a を使用できます。

そのメソッドは、次のヘルパー メソッドを使用します。

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];
}
于 2012-11-30T20:10:48.410 に答える