2016-04-05 52 views
0

私はC#を初めて使用していて、Async/Awaitを使用するケースと、Async/Awaitが新しいスレッドを作成しないことを理解してスレッドを使用するタイミングが不思議でした。Async/Await vs Threadsシナリオ

たとえば、次の10時間ごとに毎時印刷の予定を設定する場合は、以下の2つの印刷方法のどちらを使用する必要がありますか?

private async void PrintHelloAsync(int delay) 
    { 
     await Task.Delay(delay); 
     Console.WriteLine("Hello"); 
    } 

    private void PrintHelloThread(int delay) 
    { 
     Task.Run(async() => 
     { 
      await Task.Delay(delay); 
      Console.WriteLine("Hello"); 
     }); 
    } 

遅延を増やして10回PrintHelloAsyncを呼び出すか、PrintHelloThreadを使用する必要がありますか?

私はこれらの並行性の概念を正しく使用していますか?

今私は6PM、9PM、およびMidnightでタスクをスケジュールする必要があるプロジェクトに取り組んでおり、これを実行する最善の方法を見つけようとしていました。

+0

2つの機能は、基本的には同じものですが、2つ目の機能は待つことができません。 'PrintHelloThread'は" Hello "を1回だけ表示します。 –

+0

誰かがasync awaitは新しいスレッドを作成しないと言ったのですか?非同期メソッドは、いくつかの非同期作業を行うことを想定しています。呼び出しスレッドは、awaitステートメントが発生するとすぐに実行を継続します。非同期メソッドの残りのプロセスを実行するために新しいスレッドが(スレッドプールに依存して)作成される可能性があります。 –

答えて

1

二つの機能の主な違いは、最初の1がによって行われていることです2番目のスレッドはスレッドプール内の空きスレッドによって呼び出されます。

誰かが私に説明しています。比喩を使用して(ああ、私はもう彼の名前は分かりません)。

朝食を作りたいとします。いくつかのパンを焼き、卵を沸かす必要があります。

パンをトースターに入れ、パンを焼くまで待ってからトーストしたパンをトースターから取り出して沸騰した水を沸かすことができます。水が沸騰したら、卵を加え、しばらく待って水から卵を取り出して火を消す。これは同期実行の典型的な例です。

一方、トースターにパンを入れたら、すでに沸騰している水を飲むことができます。パンが焼かれるか、水が沸騰するまで待ってください。最初のケースでは、パンを取り出して水が沸騰するのを待ちます。後者の場合は、卵を水に入れ、パンを焼くか卵を準備するまで待つ。何かが起きるのを待たなければならないとすぐに、プロセスを高速化するために何か他のことを行うことができるかどうかを見ていきます。非同期実行の典型的な例です。これはasync-awaitの使用方法で、最初の関数で使用されたメソッドです。

最も高価な方法は、あなたがいくつかの卵を沸騰させるために水を加熱しながらいくつかのパンを焼くために注文する料理人を雇うことです。

スレッドが1つしかない場合は、そのスレッドがクックを実行してクックが準備ができるまでそのスレッドが待機するようにすると賢明ではありません。

スレッドに何もする必要がなければ、最初の機能を使用してください。

しかし、この最初の関数は、スレッドが非同期関数自体で実行されている場合にのみ呼び出すことができます。あなたのスレッドが非同期関数ではなく、あなたのパンがトーストされている間に何か意味のあることができる場合は、2番目の方法の使用を検討してください。

1

究極的には、6PM、9PMなどのタスクをスケジュールすることを目標としています。細部まで進まなければ、おそらく間違った方向に向かっているでしょう。代わりに、Windowsサービス内でホストされているQuartz.netまたはHangFireのようなスケジューラーシステムを調べるか、Windowsタスクスケジューラーを使って特定の時間にアプリケーションを起動することをお勧めします。

あなたはスケジューリングシステムを自分で実装するしかない場合は、私は開始とSystem.Timers.Timerクラスになります。

using System; 
using System.Threading.Tasks; 
using System.Timers; 

class Example 
{ 
    static void Main() 
    { 
     Timer timer = new Timer(1000); 
     timer.Elapsed += async (sender, e) => await HandleTimer(); 
     timer.Start(); 
     Console.Write("Press any key to exit... "); 
     Console.ReadKey(); 
    } 

    private static Task HandleTimer() 
    { 
     Console.WriteLine("Timer event"); 
    } 
} 
+0

残念ながら、すべては仕事中にかなり拘束されており、私は内部的に開発されたライブラリにしかアクセスできません。 – Ben

+0

Windowsタスクスケジューラを使用したくない、または使用できない理由はありますか? –

+0

このタスクには事前のユーザー入力が必要です。したがって、6PMで希望の値がこれになり、タスクを実行し、その値で9PMと深夜も同じです。これらの値は、ビジネス活動とユーザー側の主観に基づいて毎日変化します。 – Ben

関連する問題