2009-08-24 11 views
8

私はASP.NET MVCを使用しています。具体的には、ユーザーがダウンロードできるように大きなPDFを生成しています。 ファイルを返す長時間実行中のプロセス

  • 新しいスレッドが
  • 使用を生成しているプロセスに
  • 戻るユーザー(pdf)を伝えるビューを生成するために始めた

    1. アクションメソッドが呼び出されます:

      は、私は基本的な概念を理解しますAJAXがサーバーを呼び出して進捗状況を確認します
    2. 完了したら、ファイルをユーザーにダウンロードして提示してください。

    私は完全には理解していない部分は、以下のとおりです。

    • 別々のAJAX呼び出し間でスレッドの管理。実行中のスレッドを見つけてステータスを要求する方法が必要になるかもしれません。スレッドへの参照を保持できる静的コンテキストはありますか?私はHttpContext.Applicationのデータキャッシングを知っていますが、それはこれに適していますか?
    • 完成したファイルを提示する方法。一時ファイルを作成してダウンロードリンクを表示しますか?または、ファイルを返す最後のAJAX呼び出しを行うことはできますか?
  • +0

    優秀な質問...同じ状況で立ち往生! –

    答えて

    6

    カシェはそれに非常に適しています。キャッシュされたアイテムがプロセスの実行中に削除されないことを確認することが1つだけです(ItemPriority.NotRemovableを使用できます)。

    ファイルを一時フォルダにディスクに保存することもできますし、しばらくの間キャッシュに保存することもできます(それは依存します)。
    私は個人的にハードディスクでファイルを汚染していないので、キャッシュにファイルを保存します(数分のうちにMediumPriorityを使用)。しかし、ファイルのサイズが大きく、頻繁にファイルシステムのデータベースを使用して生成することができます生成することができます。 ({:resultUrl、 "100%": "http://your.url/Where/ToGet/TheFile.aspx?file=GUID-OR-CACHE-KEY" 進行}のように見えることができます)あなたが提供したURLにブラウザをリダイレクトすることができ、最後のAjaxリクエストが返す結果クライアント上

    、。
    これは、そのファイルをバイナリ結果としてレンダリングします。

    クライアントのリダイレクトは、次のようにJavascriptを使用して行うことができます。

    location.href = response.resultUrl; 
    

    ところで、どのようにPDFを生成していますか? NFOP?

    +0

    答えをありがとう。私はすぐにこれを試してみるつもりですので、私はどのように乗っているかを教えてくれます。 現時点で私は実際のPDFを生成する手段がありません:( – jeef3

    +0

    もう1つのことは言いたいことですが、ASP.NET MVC CodePlexサイトにAsynControllerがあります。 –

    +0

    ああ、面白い、それを調べなければならないだろう。 – jeef3

    7

    ここで

    は、私がやったものだ:

    ステップ1 & 2 - アクションメソッドが呼び出されると、長期実行中のスレッドが私のアクションメソッドが呼び出されるとき

    開始され、それはユニークなIDを生成します。 PdfGeneratorクラスのインスタンスをインスタンス化し、PdfGenerator.Generateを呼び出して起動する新しいスレッドを作成します。

    public class PdfGenerator 
    { 
        public string State; 
        public byte[] Data; 
    
        public void Generate() 
        { 
         // Generate PDF/Long running process 
         // Should update State as it goes 
         // ... 
         // Once finished, Data is populated with the binary byte[] 
        } 
    } 
    

    スレッドが起動(または開始する前に)いったん発電インスタンスがキャッシュに保存されています。それは私の見解で参照できるように

    HttpContext.Cache[guid] = generator; 
    

    また、私はViewDataをにGUIDを添付スクリプト。

    ステップ3 & 4 - 表示および更新状況/進捗ビュースレッドが実行されていて、PDFの生成が開始されたことを今

    、私は私の進捗ビュースクリプトを表示することができます。使用してjQueryの$.getJSON私は世代の状況を見つけるために、別のアクションをポーリングすることができる午前:

    [OutputCache(Duration = 0, VaryByName = "none", NoStore = true)] 
    public JsonResult CheckPdfGenerationStatus(string guid) 
    { 
        // Get the generator from cache 
        var generator = HttpContext.Cache[guid] as PdfGenerator; 
    
        if (generator == null) 
         return Json(null); 
        else 
         return Json(generator.State); 
    } 
    

    マイビュースクリプトは、JSONを解釈し、適切な進捗情報が表示されます。

    ステップ5 - 生成が完了すると、ユーザ

    に現在のファイルは、発電状態に応じて設定されているとjQueryは、この情報を受信した場合、それは、利用可能なリンクを作成し、又は直接使用してファイルを送信しますかjavascripts location.href

    設定し、ファイルを返すアクションメソッドは、単に[]

    public ContentResult DownloadPdf(string guid) 
    { 
        var generator = HttpContext.Cache[guid] as PdfGenerator; 
    
        if (generator == null) 
         return Content("Error"); 
    
        if (generator.State == "Completed") 
        { 
         return Content(generator.Data); 
        } 
        else 
        { 
         return Content("Not finished yet"); 
        } 
    } 
    

    をキャッシュから発電機を取得し、添付のバイトを返し、私は、このような初期化など、より詳細な状態を持っている私の私の実際の作業、実行中と完了しました。進捗率(10進数で表現され、1.0は完了)。

    だから、他の誰かが同様のことをしようとするのに役立ちます。

    関連する問題