5

コードを非同期で (たとえば、async/await を使用して) 実行するには、適切なタスクが必要です。もちろん、フレームワークには最も頻繁な操作をカバーする定義済みのメソッドがいくつかありますが、独自のメソッドを作成したい場合もあります。私は C# を初めて使用するので、間違っている可能性は十分にありますが、少なくとも現在のやり方には満足していません。私がやっていることについては、次の例を参照してください。

public async Task<bool> doHeavyWork()
    {
        var b1 = await this.Foo();
        //var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run
        var b2 =  await Task.Run(()=>Bar());
        return b1 & b2;
    }

public Task<bool> Foo()
    {
        return Task.Factory.StartNew(() =>
                                  {
                                      //do a lot of work without awaiting
                                      //any other Task
                                      return false;
                                  });
    }

public bool Bar()
    {
        //do a lot of work without awaiting any other task
        return false;
    }

一般的に、私はFooの例のようなメソッドを作成して使用しますが、メソッドロジック全体を含む「余分な」ラムダがあり、あまり見栄えがよくありません。もう 1 つのオプションは、Bar の例のように任意のメソッドを使用することですが、このメソッドを (BarAsync などの適切なメソッド名を除いて) 非同期で実行する必要があることが明確ではなく、Task.Factory.StartNew を実行する必要がある可能性があるため、これはさらに悪いことだと思います。プログラムで何度も繰り返されます。コンパイラに「このメソッドはタスクを返します。呼び出されたときに全体をタスクにラップしてください」と伝える方法がわかりません。これは私がやりたいことです。

最後に私の質問: このようなメソッドを作成する最良の方法は何ですか? 「余分な」ラムダを取り除くことはできますか (もちろん、名前付きメソッドを追加せずに)?

編集 Servyが述べたように、メソッドの同期バージョンを使用する正当な理由は常にあります。非同期バージョンは、絶対に必要な場合にのみ提供する必要があります (Stephen Cleary のリンク)。

4

1 に答える 1

3

Bar誰かが新しいスレッド/タスクで開始せずに電話をかけたい場合、世界は終わりますか?すでにバックグラウンドスレッドにある別のメソッドがあり、その長時間実行されているコードを実行するために新しいタスクを開始する必要がない場合はどうなりますか?メソッドが、デスクトップアプリコンテキストとASPまたはコンソールコンテキストの両方から呼び出されるクラスライブラリにリファクタリングされた場合はどうなりますか?これらの他のコンテキストでは、そのメソッドはおそらく、としてではなく、直接実行する必要がありますTask

Barいかなる状況においても、新しいコードを開始せずにそのコードを実行することが絶対に必要な場合を除いて、コードはそこにあるように見えるはずですTask

また、新しいバージョンの.NETでは、からTask.Factory.StartNewに切り替える必要がTask.Runあるため、コードの量を減らす必要があることにも注意してください(少し)。

于 2012-09-14T18:18:43.103 に答える