2009-08-03 11 views
1

長い時間がかかるASP.NETページ上で1つのステートメントが実行されています(このページを瞬時に高速にするには長すぎますが、これは長すぎます)。実行する限り実行されます。C#で単一の文を非同期にする最も簡単な方法は?

これを達成するための最善の方法(とうまくいけば簡単な方法)はありますか?

答えて

8

おそらく最も簡単な方法は、スレッドプールで実行することです。たとえば、これを非同期にするには:

using System; システムを使用しています。スレッディング; - いくつかのケースでは、微妙な副作用を持つことができます(

ThreadPool.QueueUserWorkItem(x => ExecuteLongRunningTask()); 

あなたが任意の引数を渡す場合、彼らは変数をキャプチャすることがありますことに注意してください:へMainの最初の行は

class Test 
{ 
    static void ExecuteLongRunningTask() 
    { 
     Console.WriteLine("Sleeping..."); 
     Thread.Sleep(1000); 
     Console.WriteLine("... done"); 
    } 

    static void Main() 
    { 
     ExecuteLongRunningTask(); 
     Console.WriteLine("Finished"); 
     Console.ReadLine(); 
    } 
} 

変更特にループ内で使用する場合)。

+0

..私はあなたを打ち負かそうと思っていました。:D –

+0

それは(コンセプトで)機能しましたが、別のスレッドでそのコードを実行すると何かがクラッシュしました。私はThread.Sleepを置き換えて、私が少なくとも機械力が正しいことを確認しました。このアプローチを使用すると、特定のASP.NETの問題が解消されますか?例えば、そのコードは裏でweb.configを読むかもしれません。それはそれを捨てるだろうか? – Larsenal

+0

私はあらゆる面白い副作用を得ています。 System.Data.SqlClient.SqlConnectionを開こうとすると、「ユーザーがログインできませんでした... 'XYZ'」というメッセージが表示されます。興味深いものを追跡する。 – Larsenal

0

コマンドが実行される前に応答を送信できると言うなら、ThreadPool.QueueUserWorkItemを使用してリクエストをブロックせずに別のスレッドで実行することができます。

1

.NETアプリケーションのバックグラウンドで情報を処理する際に非常に便利なバックグラウンドワーカースレッドがあります。もう少し文脈があれば、より良い質問に答えるのに役立ちます。

+0

どのようなコンテキストが役に立ちますか?私は後世には役に立たないと思うほど質問をしたくなかった。 – Larsenal

+0

私はあなたの特定の状況に対して可能な限り最良の答えを出したいと思っていましたが、言及された他のすべての提案は、私が議論していた他の選択肢をカバーしていました。 – JCab

3

100msの場合は、気にしないでください。ユーザーは100msの遅延を検出できません。


編集:いくつかの説明。

私が正しく覚えていれば、100ミリ秒(1/10秒)は人間が知覚できる最小時間に近いです。議論の目的のために、私はこの100msはOPのサイトのユーザーによって知覚されることができ、パフォーマンスを100ms向上させることは価値があることを認めます。私は最初から、営業担当者が100msの改善の潜在的な源泉であると見なしていました。だから、なぜ彼はそれを無視することを提案したのですか?

複数のスレッドを適切に処理することは容易ではなく、追跡が困難なバグの原因です。問題にスレッドを追加するのは、通常は解決策ではありませんが、すぐに見つからない他の問題の原因になります(*)。

私は、一度このハードな方法を学ぶ機会がありました。その時点で入手可能な最速の8CPUシステムでしか再現できなかったバグがありました。その後、度量をシミュレートしながら、それが実際の状況で起こった場合、ネットワーク管理者が整列して撃たれてしまったネットワーク障害が発生していました。この不具合はUnixのOSカーネルでのシグナルの処理にあることが判明し、一握りの指示の配列の問題であった。

私はそれ以来、それほど悪くは見たことがない、私はまだ多くの開発者がマルチスレッドバグによってトリップしたのを見た。この質問は、一方ではスレッディングによる「簡単な方法」を求めていたようでした。一方、利益はわずか100msでした。 OPはすでに十分にテストされたスレッディングインフラストラクチャを持っていないように見えたので、100msを無視するか、あるいは別の方法でパフォーマンスを拾うのが良いと感じました。もちろん


(*)、アルゴリズムは有利に複数のコア上で実行されている、複数のスレッドによって並列作られ、実行することができる多くの状況があります。しかし、それはOPがそのようなケースを持っているようには聞こえません。

+0

Downvoter:downvoteの理由を共有するために気をつけますか? –

+0

なぜGoogleはそんなに好きですか?私は彼らが1日に50回自分の時間の100msを無駄にしないことをうれしく思っています。 –

+1

あなたの答えは質問に対する答えではないので、私は下降しました。 OPは "私は100msのために最適化する時間を無駄にしていますか?彼は100msの遅れを取り除く方法を尋ねた。私はクラウド規模のWebサービスを構築しています。平均応答時間は、OPがすでに確認しているこの低い吊り下げの果物を無視して、100msを大幅に下回る必要があります。 –

1

// This is the delegate to use to execute the process asynchronously 
public delegate void ExecuteBackgroundDelegate(); 

// 
[STAThread] 
static void Main(string[] args) 
{    
    MyProcess proc = new MyProcess(); 

    // create an instance of our execution delegate 
    ExecuteBackgroundDelegate asynchExec = new ExecuteBackgroundDelegate(proc.Execute); 

    // execute this asynchronously 
    asynchExec.BeginInvoke(null, null); 
} 
+0

あなたはまた私達にAction ... new Action(()=> proc.Execute).BeginInvoke(null、null); –

+0

うわー、ありがとう!私はそれについて知らなかった。私はちょうど1.1以前の単一のC#言語リファレンスを持っていないことを認識しました。 –

0

スレッドプールを使用できます。

ThreadPool.QueueUserWorkItem(o => Thread.Sleep(1000) /*your long task*/ ); 
0
class Test 
{ 
    void LongRunningTask() 
    { 
     Console.WriteLine("Sleeping..."); 
     Thread.Sleep(10000); 
     Console.WriteLine("... done"); 
    } 

    static void Main() 
    { 
     Test t = new Test(); 
     new Action(() => t.LongRunningTask()).BeginInvoke(null, t); 
    } 
} 
0

私は100msの遅延のためにそのスレッドのもののいずれかと気にしないでしょう。これは問題ないでしょう。

protected void Page_Unload(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.Flush(); 
    HttpContext.Current.Response.Close(); 

    // Your code here 
} 

あなたのページをダウンロードし、クライアントへの接続が閉じられますので

this questionのために私の以前の回答からコピーされた)、そのブラウザが読み込みメッセージの表示を停止します。ただし、コードは通常どおり実行されます。

関連する問題