2016-09-29 19 views
2

C#のスレッディングを理解していないので、スレッドについての簡単な説明を探しています。具体的には.NET 4のStartNew()機能です。Threading .StartNew()and .Wait()

私は次のようにして、一種のfire-and-forget手法で別のメソッドを呼び出します。ウェブページが時間のかかるプロセスを開始する必要があるときに、ページが実際に結果を待つ必要がない場合は、これを行うことがあります。私が理解しているように、DoSomething()メソッドは "非同期に"実行されます。私は私は本当に、その目的のためにそれを使用していないという卑劣な疑いを持っているが -

System.Threading.Tasks.Task.Factory.StartNew(() => 
{ 
    DoSomething(); 
}); 

上記のコードは、私はそれをしたいだけのように動作するようです。私はまた、DoSomething()メソッドが実行される前に閉じていたコンソールアプリケーションでそれを使用しています。なぜそれがWebページ上で動作するのかコンソールアプリケーションではないのか分かりません - ページがアンロードされてもアプリケーションプールが動いているので、私は仮定しています。

実際に私を混乱させることは、私が.Wait()でそのようなコードを終了する例をたくさん見てきたことです。私が理解しているように、.Wait()は、このページの残りのコードがDoSomething()メソッドが実行されるまで待つことを意味します。この場合、私の限られた理解では、これは最初のStartNew()?

誰かが私の簡単な小さな心が理解する方法でこれを説明するのを助けてくれることを願っています!おそらく、あなたはまた、火災と忘れたアプローチでメソッドを呼び出すより良い方法を説明することができますか?どうもありがとう!

+3

あなたは、ASP.NET内のスレッドを作成することはほとんどないはずです。また、より良い火災と忘れて使用http://hangfire.io/ –

答えて

2
System.Threading.Tasks.Task.Factory.StartNew(() => 
{ 
    DoSomething(); 
}) 

これは、基本的には、作業をスレッドプールにオフロードします。スレッドが利用可能になると、スレッドは使用されます(つまり、ThreadPoolが満たされている場合、実際には異なる時間に実行される可能性があります)。

最後に.Wait()を呼び出すと、そのタスクが実行を終了するまでブロックされます。基本的には、完了するまでメインスレッドを実行させません。 そして、DoSomething()の実行時間に応じてパフォーマンスの問題が発生する可能性があります。

より良い方法は、を使用して、アプリケーションがメインThreadを縛らずに応答し続けることができるようにすることです。

また、StartNewではなくTask.Runを使用する必要があります。他のパラメータ(キャンセルトークンやスケジュールなど)を提供する必要がない限り、Task.Runがデフォルトの使用方法です。

// fire and forget, this will run on a thread once one is available on the thread pool 
Task.Run(()=> 
{ 
    DoSomething(); 
}); 

// fire and wait until exeuction has finished. this will block all activity until it is done 
Task.Run(()=> 
{ 
    DoSomething(); 
}).Wait(); 

// fire and and wait until the task is completed but do not block the current thread. 
private async void DoSomethingAsync() 
{ 
    await Task.Run(()=> 
    { 
     DoSomething(); 
    }); 
    // perform work after 
} 

注: "それはIIS自体によってスレッドに懸濁させることができるようにASP.NETアプリケーション内のタスクは危険かもしれない出発" VMAtmに述べたように 、例えば

なぜ危険ですか?

  • 要求に関連付けられていないスレッドの未処理の例外は、処理を中止します。
  • Webファームでサイトを実行すると、同じタスクを同時に実行しようとするアプリケーションの複数のインスタンスが終了する可能性があります。
  • サイトが実行されているAppDomainは、いくつかの理由から停止し、バックグラウンドタスク を削除することができます。

さらに詳しい情報:ASP.NETアプリケーションでタスクを実行する方法http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/

http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx

+2

あなたはASP.NETアプリケーションでタスクを開始することが危険であることに注意してくださいそれはIIS自体によってスレッドで中断することができます – VMAtm