2012-03-28 17 views
6

時間のかかるプロセス(ネットワークから大きなファイルをコピーする)を処理するASP.NET MVC3アプリケーションがあります。私たちがやりたいことはある:ASP.NET MVCの非同期リクエストの処理

  1. ユーザーがプロセスに
  2. アプリケーションを起動するために、フォームを投稿するボタンをクリックするには
  3. アプリケーションがファイルのコピーを言ってメッセージを表示、ファイルのコピーを開始するために、新しいスレッドを開始します処理が開始されました
  4. コピーが処理され、バックグラウンドで終了している間、ユーザーはブラウザを閉じることができます。

ユーザーはプロセスの進行状況を確認する必要はなく、プロセスが完了したときに通知を受けることができます。

現在、コントローラはWindowsサービスでイベントをトリガし、Windowsサービスを使用して実際の作業を行います。私はこれを行うためのより良い/クリーンな方法があるのだろうか?

+3

MVC 3については、MSDNの記事を参照してください。http://msdn.microsoft.com/en-us/library/ee728598(VS.98).aspx MVC 4とDeveloper Express 11を使用できる場合は、はるかに簡単な新しいAsync/MVCチュートリアルを作成します。 – RickAndMSFT

答えて

6

StartNewメソッドをAction delegateで呼び出すと、System.Threading.Tasks.Taskを使用できます。お使いのコントローラがこのようなものになり、これらのツールの使用

[HttpPost] 
public ActionResult DoSomethingLongRunning() 
{ 
    if (ModelState.IsValid) 
    { 
     Task.Factory.StartNew(() => 
        fileCopier.CopyFile(CopyFileParameter1, CopyFileParameter2)); 

     return RedirectToAction("View Indicating Long Running Progress"); 
    } 
    else 
    { 
     // there is something wrong with the Post, handle it 
     return View("Post fallback view"); 
    } 
} 

別のオプションは、(おそらく、コントローラのコンストラクタに注入されたアクションを実行するための具体的な実装としてTaskPoolSchedulerSystem.Reactive.ConcurrencyISchedulerインタフェースを使用することができています。利点として

public ActionResult DoSomethingLongRunning() 
{ 
    if (ModelState.IsValid) 
    { 
     ISchedulerImplementation.Schedule(new Action(() => 
     { 
      fileCopier.CopyFile(CopyFileParameter1, CopyFileParameter2); 
     })); 
     return RedirectToAction("View Indicating Long Running Progress"); 
    } 
    else 
    { 
     // there is something wrong with the Post, handle it 
     return View("Post fallback view"); 
    } 
} 

、あなたはそれをあなたはユニットテストされているインタフェースの実装として TestSchedulerを使用することができますこの方法を行う場合。

+0

それは代案かもしれませんが、この場合は最善の解決策ではありません。ユーザーはトリガーされたプロセスの完了を通知される必要はないため、Windowsサービスが完全に分離されているため、Webサーバーがダウンしても機能します。 –

3

私はあなたの長期的なプロセスは、Windowsサービスホストを持つことが最良の賭けだと思います。 IISによってホストされている場合は、実行中のアプリケーションプールがアクティブでないために殺される危険性が常にあります。

関連する1つの可能性は、Windowsサービス内でWCFサービスをホストし、そのサービス用の外部HTTPまたは他のエンドポイントを提供することです。そうすれば、WebインターフェイスはWCFサービスの "開始"契約メソッドを呼び出すことができ、必要に応じて他のメソッドを呼び出すことができます。

+0

いいえ、IIS上のすべてのものをホストしている(異なるアプリケーションプール下でも)createはプロセスを分離せず、プロセスを独立させません。 IISが停止すると、すべてが停止します。また、IISまたはWindowsサービスでのホスティングの違いについては、このリンクを参照してください。http://social.msdn.microsoft.com/Forums/en/wcf/thread/015d711d-ce5a-46a1-a93e-1c68746e76d3 –

2

IIS 7 WASでホストされているWCF MSMQサービスにリクエストを送信します。設定方法はan awesome articleです。

外部リソースを使用して長時間実行されるタスクは、失敗する危険性が高くなります。開発者がしばしば直面する最大の間違いは、ハードウェアとネットワークが無限の容量を持ち、信頼性が高いと仮定することです。それはしばしばではありません。

一時的にネットワーク接続が失われたり、リモートサーバーが再起動したりすると、長時間実行されていたプロセスが中断されると、問題が発生することもあります。長時間実行しているプロセスにファイルの解凍や解析などの追加処理が含まれている場合、処理を実行するための十分なメモリがない場合、さらに障害が発生する可能性があります。ユーザーはあまりにも多くのリクエストを提出することがあり、同時の問題を処理するのに十分なリソースがありません。 ASP.NET MVCアプリケーションでasync controllersの処理を実行させると、IISが作業プロセスをリサイクルするときに長時間実行されていたプロセスが中断された場合に驚くことがあります。

MSMQ 4は、これらのリスクを緩和するためにはかなり良い仕事をしています。プロセスが失敗した場合は、数回再試行してから中止してください。あなたはそれを設定する方法を学ぶことができますhereapplication specific deadletter queuesを使用して、受け入れ可能な試行回数の後にプロセスが失敗した場合を処理できます。これは運用スタッフが問題を診断する上で重要です。このスキームを使用して、要求の発信元マシンがオフになっていても、プロセスが失敗した(または成功した)ことを電子メールでユーザに通知することもできます。

WindowsサービスではなくIISでホストすると、追加機能が提供されます。たとえば、IISワーカープロセスがデッドロック状態になるか、メモリのしきい値を超えると、リサイクルできます。後者は、処理を実行するためにネイティブコードを使用しているときに問題になる可能性があります。あなたは4時間ごとにリサイクルすることができます(あなたの時間枠を選んでください)。後者は、時間の経過とともに大きなオブジェクトヘッドが断片化し、別の大きな要求に対して十分なメモリを管理することがほとんど不可能になるため、管理されたメモリの大きなブロブで作業する場合はかなり重要です。 WindowsサービスでホストされているWCFサービスにこの問題が発生することがあります。

実際には、そのバックグラウンドプロセスをどれだけ信頼できるものにするかによって異なります。そうでない場合、WCFを使用すると、MSMQとIISは単に過剰なものになることがあります。

関連する問題