2016-05-23 3 views
0
public async Task<ActionResult> Search(string q) 
    {  
     var data = db.MediaPlanBilingInvoices.Where(m => m.IsDeleted == false); 
      //allthe stuff   


      decimal? allinvoicetotal=0; 
      decimal? allrototal = 0; 
      if (Noofrecords > 0) 
      {     
        if (WebConstants.PrintMedia) 
        { 
         var roobject = data.Where(x => x.isPrint == true).SelectMany(m => m.MediaPlanBilingInvoiceDetails); 
         var roobjects =roobject.Select(m=>m.RoId); 

         Func<decimal?> functions = new Func<decimal?>(() => roobject.Sum(m => m.MediaPlanRO.MediaPlanROPrints.Sum(qq => qq.MediaPlanPrint.Amount))); 
         var tasksro = await System.Threading.Tasks.Task.Factory.StartNew<decimal?>(functions);  


         allrototal = allrototal + tasksro.Result; 

       } 
       else if (WebConstants.ElectronicMedia) 
       { 
        var roobject = data.Where(x => x.iselectronic == true).SelectMany(m => m.MediaPlanBilingInvoiceDetails); 
        var roobjects =roobject.Select(m=>m.RoId); 

        Func<decimal?> functions = new Func<decimal?>(() => roobject.Sum(m => m.MediaPlanRO.MediaPlanROPrints.Sum(qq => qq.MediaPlanPrint.Amount))); 
        var tasksro = await System.Threading.Tasks.Task.Factory.StartNew<decimal?>functions); 


        allrototal = allrototal + tasksro ; 
       } 
       }     
      } 

       return Viewdata); 
      } 
     } 

異なる基準で異なるテーブルのrosの合計を計算しようとしています。asp.net mvc asyncメインスレッドをブロックしないようにすることを待ちます

問題があるのは、プログラムリーチャーallrototalが停止し、結果が失われるまで次の行に移動しないという問題です。私はそこに止まらないように走り続けたい。どうすればいい?

+0

これはasync/awaitとは何ですか。それは他の要求がそれを使用できるようにスレッドを非ブロッキングにします。 – Dandy

+1

これはasync/awaitがどのように動作するかを示しています。結果が得られるまでは使用できません。 –

+0

pgogramがstartnewを見つけるとすぐに、バックグラウンドでクエリの実行が開始されますか? – maztt

答えて

4

あなたが持っているコアの問題は、async doesn't change the HTTP protocolです(私のブログで詳しく説明しています)。 HTTPでは、1つのリクエストと1つのレスポンスがあります。応答を返せば、でもに何か他のものが実行されていて、返信することができません。もう1つ応答が返ってきます - HTTPはそのようには動作しません。

ので、ASP.NETに、asyncあなたはスレッドを解放することができますが、応答を完了していません。 asyncメソッドが終了するまで、応答は送信されません。

さらに、Task.Run is safer than StartNewでも、のいずれもは、ASP.NETでこのように使用する必要があります。これは、要求スレッドプールスレッドを別のスレッドプールスレッドを使用して解放しているためです。だからawait Task.Run(() => functions());はちょうどfunctions()と言うより高価な方法です。

この方法は同期させるだけです。ここでは非同期的な作業はありません。クライアントが非同期に動作するようにするには、クライアントが非同期的にHTTP要求を行う必要があります。

+0

非同期に関する記事がたくさんあります。上記の50秒のクエリを5秒間の10秒間のクエリに分解するとどうなるでしょうか?多くのスレッドに? – maztt

+0

10秒間のクエリが並行して実行中 – maztt

+0

@ maz3tt:危険です、IMO。確かに試してみることもできますが、現実的な負荷条件でテストする必要があります。あなたのリクエスト数が常に少ないということが分かっていない限り、ASP.NETの並列性は通常、本番環境ではうまく機能しません。これに当たる各要求は、1で​​はなく5つのスレッドを占有し、スレッドは要求の中で最も重いリソースの1つなので、サーバーのスケーラビリティはかなり制限されます。 –

関連する問題