4

タスクを非同期的に遅延させるのに問題があります。私は、数万から数十万の非同期実行スクリプトを実行する必要があるアプリケーションを書いています。私はC#アクションを使用してこれを行っています、そして時々、特定のシーケンスの実行中に、スクリプトが適切に実行されるためには、外部リソースが期待される状態に達するのを待つ必要があります。最初はThread.Sleep()を使用してこれを記述しましたが、これはアプリケーションパフォーマンスの魚雷であることが判明したため、async / async sleepを検討しています。しかし、私は実際に休止を待つことができません!誰かがこれを説明できますか?

static void Main(string[] args)
    {
        var sync = new List<Action>();
        var async = new List<Action>();

        var syncStopWatch = new Stopwatch();
        sync.Add(syncStopWatch.Start);
        sync.Add(() => Thread.Sleep(1000));
        sync.Add(syncStopWatch.Stop);
        sync.Add(() => Console.Write("Sync:\t" + syncStopWatch.ElapsedMilliseconds + "\n"));

        var asyncStopWatch = new Stopwatch();
        sync.Add(asyncStopWatch.Start);
        sync.Add(async () => await Task.Delay(1000));
        sync.Add(asyncStopWatch.Stop);
        sync.Add(() => Console.Write("Async:\t" + asyncStopWatch.ElapsedMilliseconds + "\n"));

        foreach (Action a in sync)
        {
            a.Invoke();
        }

        foreach (Action a in async)
        {
            a.Invoke();
        }
    }

実行結果は次のとおりです。

同期:999

非同期:2

非同期に待機させるにはどうすればよいですか。

1 답변


7

に問題が発生していますasync void。合格するとasyncラムダからAction、コンパイラが作成していますasync voidあなたのための方法。

ベストプラクティスとして、避けるべきですasync void

これを行う1つの方法は、あなたの行動のリストを実際にはList<Func<Task>>の代わりにList<Action>。これにより、キューに入れることができますasync Taskの代わりにメソッドasync voidメソッド

これはあなたの "実行"コードがそれぞれを待つ必要があることを意味しますTask完了しました。また、同期メソッドは返さなければなりませんTask.FromResult(0)またはそのようなものは彼らが一致するようにFunc<Task>署名。

もっと大きなスコープのソリューションが必要な場合は、独自のキューを作成するのではなくTPLデータフローを強く検討することをお勧めします。

関連する質問

最近の質問