2009-08-24 34 views
8

Tôi đang sử dụng ASP.NET MVC và có quy trình chạy dài. Cụ thể là tôi đang tạo một tệp PDF lớn để người dùng tải xuống.Quá trình chạy dài sẽ trả về một tệp

Tôi hiểu các khái niệm cơ bản:

  1. phương pháp hành động được gọi
  2. chủ đề mới bắt đầu để tạo ra quá trình
  3. Return một Xem mà nói cho người dùng (pdf) đang được tạo
  4. Sử dụng AJAX để gọi cho máy chủ và yêu cầu tiến trình
  5. Sau khi hoàn tất, hãy trình bày tệp cho người dùng để tải xuống.

Các bộ phận tôi không hoàn toàn hiểu là:

  • Việc quản lý các chủ đề trên riêng AJAX gọi. Tôi có thể sẽ cần một số cách để tìm chuỗi chạy và yêu cầu một trạng thái. Có một bối cảnh tĩnh tôi có thể giữ một tham chiếu đến các chủ đề trong? Tôi biết về Caching dữ liệu trong HttpContext.Application, điều đó có phù hợp với điều này không?
  • Và cách trình bày tệp hoàn chỉnh. Tôi có tạo tệp tạm thời và hiển thị liên kết tải xuống không? Hoặc tôi có thể thực hiện cuộc gọi AJAX cuối cùng trả về tệp không?
+0

Câu hỏi hay ... bị kẹt trong cùng một tình huống! –

Trả lời

6

Tiền mặt rất phù hợp cho điều đó. Chỉ có một điều là để đảm bảo mục được lưu trữ không bao giờ bị xóa trong khi quá trình đang chạy (Bạn có thể sử dụng ItemPriority.NotRemovable cho điều đó).

Bạn có thể lưu tệp trên đĩa trong thư mục tạm thời hoặc bạn có thể lưu tệp trong bộ nhớ cache trong một thời gian (tùy thuộc).
Cá nhân tôi không muốn gây ô nhiễm đĩa cứng với các tệp để tôi giữ tệp trong bộ nhớ cache (với MediumPriority trong vài phút). Nhưng tệp lớn và có thể được tạo thường xem xét sử dụng Cơ sở dữ liệu của hệ thống tệp thay thế. Trên máy khách, khi yêu cầu Ajax cuối cùng trả về kết quả (có thể giống như {tiến trình: "100%", resultUrl: "http://your.url/Where/ToGet/TheFile.aspx?file=GUID-OR-CACHE-KEY"}), bạn có thể chuyển hướng trình duyệt đến một url được cung cấp.
Đổi lại, sẽ hiển thị tệp đó dưới dạng kết quả nhị phân.

khách hàng chuyển hướng có thể được thực hiện sử dụng Javascript như thế này:

location.href = response.resultUrl; 

BTW, làm thế nào để bạn tạo ra PDF? NFOP?

+0

Cảm ơn câu trả lời. Tôi sẽ cung cấp cho một thử một thời gian ngắn như vậy sẽ cho bạn biết làm thế nào tôi nhận được trên. Hiện tại tôi không có phương tiện để tạo tệp PDF thực tế: ( – jeef3

+0

Một điều khác mà tôi quên đề cập. Có AsynController trên trang ASP.NET MVC CodePlex. Nó có thể hữu ích cho bạn. Tôi nghĩ nó tóm tắt từ luồng –

+0

Oh wow, thú vị, sẽ phải nhìn vào đó. – jeef3

7

Nó hoạt động!

Đây là những gì tôi đã thực hiện:

Bước 1 & 2 - Hành động Phương pháp được gọi là, dài chạy thread được bắt đầu

Khi phương pháp hành động của tôi được gọi, nó tạo ra một ID duy nhất. Sau đó, tôi khởi tạo một thể hiện của lớp PdfGenerator của mình, tạo một chuỗi mới gọi PdfGenerator.Generate và khởi động nó.

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[] 
    } 
} 

Khi thread đã bắt đầu (hoặc trước khi bắt đầu) trường hợp máy phát điện được lưu trữ trong bộ nhớ cache:

HttpContext.Cache[guid] = generator; 

Tôi cũng gắn guid để ViewData để nó có thể được tham chiếu trong quan điểm của tôi kịch bản.

Bước 3 & 4 - Hiển thị và cập nhật tình trạng/tiến độ xem

Bây giờ thread đang chạy và tạo PDF đã bắt đầu, tôi có thể hiển thị view script tiến bộ của tôi. Sử dụng jQuery $.getJSON tôi có thể thăm dò ý kiến ​​một hành động riêng biệt để tìm thấy trạng thái của thế hệ:

[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); 
} 

xem kịch bản của tôi diễn giải Json và hiển thị thông tin tiến bộ phù hợp.

Bước 5 - Hiện tại tập tin để sử dụng

Khi thế hệ đã hoàn thành, tình trạng máy phát điện được thiết lập cho phù hợp và khi jQuery nhận được thông tin này, nó có thể hoặc là làm cho có sẵn một liên kết, hoặc trực tiếp gửi hồ sơ sử dụng javascripts location.href.

Phương pháp hành động mà thiết lập và trả về tập tin đơn giản được máy phát điện ra khỏi bộ nhớ cache và trả về byte kèm theo []

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"); 
    } 
} 

tôi công việc thực tế của tôi, tôi đã có trạng thái chi tiết hơn như khởi tạo , Chạy và hoàn thành. Cũng như tỷ lệ phần trăm tiến độ (được biểu thị dưới dạng thập phân, 1.0 đang hoàn thành).

Vì vậy, vâng, hy vọng sẽ giúp bất kỳ ai khác cố gắng làm điều gì đó tương tự.

Các vấn đề liên quan