381

を使用する正しいアーキテクチャについて、ご意見をお聞かせくださいTask.Run。WPF .NET 4.5 アプリケーション (Caliburn Micro フレームワークを使用) で UI の遅延が発生しています。

基本的に私はやっています(非常に単純化されたコードスニペット):

public class PageViewModel : IHandle<SomeMessage>
{
   ...

   public async void Handle(SomeMessage message)
   {
      ShowLoadingAnimation();

      // Makes UI very laggy, but still not dead
      await this.contentLoader.LoadContentAsync();

      HideLoadingAnimation();
   }
}

public class ContentLoader
{
    public async Task LoadContentAsync()
    {
        await DoCpuBoundWorkAsync();
        await DoIoBoundWorkAsync();
        await DoCpuBoundWorkAsync();

        // I am not really sure what all I can consider as CPU bound as slowing down the UI
        await DoSomeOtherWorkAsync();
    }
}

私が読んだ/見た記事/ビデオから、await async必ずしもバックグラウンドスレッドで実行されているとは限らず、バックグラウンドで作業を開始するには、 await でラップする必要があることを知っていTask.Run(async () => ... )ます。を使用async awaitしても UI はブロックされませんが、UI スレッドで実行されているため、遅延が発生しています。

Task.Run を配置するのに最適な場所はどこですか?

私はちょうどいいですか

  1. これは .NET のスレッド化作業が少ないため、外部呼び出しをラップします。

  2. Task.Run、または他の場所で再利用できるようにするため、内部で実行されているCPUバインドメソッドのみをラップする必要がありますか? コアの奥深くにあるバックグラウンド スレッドで作業を開始することが良い考えかどうかは、ここではわかりません。

広告 (1)、最初のソリューションは次のようになります。

public async void Handle(SomeMessage message)
{
    ShowLoadingAnimation();
    await Task.Run(async () => await this.contentLoader.LoadContentAsync());
    HideLoadingAnimation();
}

// Other methods do not use Task.Run as everything regardless
// if I/O or CPU bound would now run in the background.

広告 (2)、2 番目のソリューションは次のようになります。

public async Task DoCpuBoundWorkAsync()
{
    await Task.Run(() => {
        // Do lot of work here
    });
}

public async Task DoSomeOtherWorkAsync(
{
    // I am not sure how to handle this methods -
    // probably need to test one by one, if it is slowing down UI
}
4

2 に答える 2