2016-03-19 9 views
0

私は自分自身を青色に読んだことがあり、簡単な答えがあることを望んでいます。コントローラから戻って非同期メソッドが完了するのを待たずに

"野生の中の"さまざまなアプリからテレメトリを処理するウェブAPIがあります。私のコントローラの1つで、私の中央監視データベースにエラーを記録し、私は、呼び出し側がどのように重要なパフォーマンスを発揮しているのかを知る実際の方法はなく、最初のWebサービス要求を作成するためにはかなりのヒットです。

public IHttpActionResult Submit() { 
    try { 
     var model = MyModel.Parse(Request.Content.ReadAsStringAsync().Result); 

     // ok, I've got content, now log it but don't wait 
     // around to see the results of the logging, just return 
     // an Accepted result and begone 

     repository.SaveSubmission(model); // <-- fire and forget, don't wait 

     return Accepted(); 

    } catch (Exception) 
     return InternalServerError(); 
    } 
} 

それはそれは簡単であるべきが、どうやらないように思える:

基本的に、私が探しているこのようなものです。私はからすべてを示すさまざまな投稿をいくつでも読んだだけです。Task.Run()を使用してくださいこれはひどい間違いで、あなたが望むものを達成することはできません!

私のシナリオでの問題は、非同期メソッドを呼び出すさまざまな方法の迷路に関係なく、このプロセスがASP.NETワーカープロセスで実行されているため、最後の2時間かそこらで様々なSOの質問とStephen Clearyのブログを読んで過ごす。

この場合の根本的な問題は、私が「発砲して忘れる」メソッドがhttpコンテキストにバインドされていて、ASP.NETワーカープロセスによって早期終了することがある場合です。

このメソッド/タスク/プロセスをそのASP.NETコンテキストから削除する方法はありますか?その要求がモデルに解析されると、私自身はhttpコンテキスト内で動作する必要はもうありません。簡単な方法があれば、私はそこから移動することができます(そして、ウェブサイト/アプリケーションプールの再起動を禁止することができます)。

public IHttpActionResult Submit() { 
    try { 
     var model = MyModel.Parse(Request.Content.ReadAsStringAsync().Result); 

     SomeStaticClass.SaveSubmission(model); // <-- fire and forget, don't wait 

     return Accepted(); 

    } catch (Exception) 
     return InternalServerError(); 
    } 
} 

...そして唯一の事を「クロスを持っている:デューデリジェンスの便宜上

、のは、私は、コントローラ内のリポジトリコンテキストを取り除くと言うと、他のいくつかの文脈にそれを委任してみましょうlines "はモデル自体であり、他のコードロジックの依存関係はありません。

私は恐らく山腹を作っています - データベースへの挿入はとにかく時間がかかりません...それは簡単だと思われますが、私も明らかにそうです今夜は "十分に良い"のために頑固に頑張ってください。

答えて

1

[OK]をクリックすると、実際に私のシナリオに役立ついくつかのものが見つかりました。その基本的な要点はではないようです。

これを正しく実行するには、これを分散アーキテクチャーの別のコンポーネント(たとえば、処理のために別々に取得できる何らかのメッセージキューまたはサービスキュー)に送信する必要があります。これは、ASP.NETワーカープロセスから完全に脱出する唯一の方法と思われます。

S/Oコメント(別のS/O投稿へ)は、私がまだ投稿していない2つの記事、Stephen ClearyとPhil Haackによるものです。

SO関心のポスト:How to queue background tasks in ASP.NET Web API

シュテファン火災やASPに忘れてください。NETのブログ記事(優れた、私が最初にこれを発見した希望):http://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html

そしてフィルの記事:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/

スティーブンによって次のプロジェクトは、同様に興味がある可能性がありますhttps://github.com/StephenCleary/AspNetBackgroundTasks

私は私がしようと思いました私の質問を削除しましたが、私の答えを見つけるために長い間掘り下げてしまったかもしれないと思っていたかもしれません。おそらく別の質問が痛いわけではないでしょう...

(この特定のケースでは、とにかくデータベースに書き込む限り、s oおそらく、このapiメソッドの非同期処理を先延ばしにするでしょうが、少なくとも私が実際にそれを行う必要があるときはいつも知っています)

1

データベースの挿入にかかる時間がかかるので、処理をオフロードする必要はありませんバックグラウンドタスクに割り当てます。まずタスクをキューに書き込むだけで(あるいは、提案したように、サービスに渡す)、ちょっと時間がかかりますが、いずれのアプローチも1秒未満にする必要があります。

しかし、時間が重要な場合は、レスポンス時間を短縮する方法の1つは、メモリー内のキャッシュの形式を使用してデータベースをできるだけ高速で書き込み、物理データベース記憶域への書き込みが遅くなるようにすることですバックグラウンドタスク。大量のサイトでは、この種の動作を実装するメモリ内のデータベースが頻繁に使用されます(私はこれを必要としないため、製品を選択する手助けはできません)が、アプリケーションごとのインスタンスリスト何らかの形のバックグラウンドループがあります。

これはあなたがリンクした記事が適用され、複雑になるため、あらかじめ構築された実装がほとんど常に最良のアプローチです。事前に構築された防火と忘却の実装を希望する場合はHangFireをチェックしてください。

+0

お返事ありがとうございます。私はdbの書き込みは重要ではないことを認識していますが、当初はその意味を理解することなく「なぜ」ではないと考えました。私はこのシナリオの考えを落としました。私はこれを研究している私の旅行でHangFireに出くわしました。そして実際に必要が生じたときには、心に留めておきます。 – jleach

関連する問題