2012-10-23 32 views
7

.net 4.5, asp.net mvc: cách tốt nhất để chạy quá trình lâu dài (1-2 phút) từ ứng dụng ASP.NET cho nó nên được chạy trong một môi trường đơn luồng, ý tôi là quá trình này là bắt đầu cho một người dùng tại một thời điểm duy nhất, thực thi cho tất cả người dùng khác phải đợi cho đến khi thực hiện hiện tại được thực hiện? Kịch bản như sau: nút nhấp của người dùng chạy một số loại tính toán lâu dài, phản hồi http được trả lại cho người dùng ngay lập tức, sau đó người dùng phải yêu cầu trạng thái của các phép tính với yêu cầu riêng theo cách thủ công. Asp.net http phá thai phiên không nên dẫn đến chấm dứt quá trình, nó nên tiếp tục đi. Quá trình có thể chạy trên cùng một máy chủ hoặc riêng biệt.Làm thế nào để chạy quá trình lâu dài không đồng bộ theo asp.net?

+0

Bạn có thể thêm dịch vụ trên máy tính không? – Patrick

+0

Tôi có thể, nhưng tôi tự hỏi làm thế nào để cung cấp thực hiện liên tiếp cho mỗi thread ứng dụng web? – YMC

Trả lời

3

Tôi khuyên bạn nên sử dụng một sản phẩm như NServiceBus để giảm tải xử lý và chạy nó ở chế độ chỉ một luồng. Ưu điểm của việc này là tất cả các yêu cầu sẽ được xử lý theo thứ tự và việc xử lý có thể được tải xuống từ máy chủ web vì bạn không thực sự muốn các quy trình chạy dài xảy ra trên máy chủ web.

+0

Chúng tôi đang thực sự xem xét các tùy chọn này. Có những ưu điểm như bạn đã đề cập, nhưng có những nhược điểm cũng như thiết lập cơ sở hạ tầng cần thiết: MSMQ, tạo hàng đợi thông báo, cấu hình riêng biệt – YMC

+0

NServiceBus sẽ xử lý rất nhiều điều đó cho bạn (cài đặt và cấu hình MSMQ & DTC) được thiết kế để giải quyết vấn đề bạn đã đề cập. –

+0

Tôi thích NSBus, có lẽ đó là giải pháp tốt nhất cho chúng tôi, nhưng ý tôi là sẽ có thêm một số chi phí hành chính cho giải pháp này như sau: 1) MSMQ, RavenDb, và có thể cần phải cài đặt một thứ khác. phải tải xuống và cài đặt chúng riêng biệt, chúng không phải là một phần của gói NSBus, 2) Ai đó cần kiểm tra hàng đợi thông báo không thành công, thêm vào tệp nhật ký thông thường của chúng tôi (hai điểm theo dõi ứng dụng thay vì một) 3) để có cấu hình riêng của nó (hai tập tin cấu hình để quản lý thay vì một) – YMC

0

Tôi sẽ xem xét điều này, được viết bởi Phil Haack, giải thích các vấn đề bạn có thể đang chạy các tác vụ nền trong một ứng dụng web. http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

+2

Đó là một bài viết tuyệt vời trong ngày của nó, nhưng nó đã lỗi thời (ít nhất là cho WAWS) bây giờ. Xem Azure WebJobs của tôi trả lời – RickAndMSFT

4

.Net 4.5.2 thêm QueueBackgroundWorkItem mà bạn có thể sử dụng để lên lịch cho tác vụ. Nếu bạn không kiểm soát máy chủ (khi khởi động lại), thời gian trễ mặc định là 90 giây của appPool sẽ không hoạt động (trừ khi bạn có thể phát hiện tác vụ không hoàn thành và chạy nó trên máy chủ khác). Để biết thêm chi tiết, hãy xem "QueueBackgroundWorkItem to reliably schedule and run background processes in ASP.NET"

12

Tôi sẽ chỉ cho bạn cách thực hiện tác vụ này với http://hangfire.io - cách vô cùng dễ dàng để thực hiện các tác vụ lửa và quên, bị trì hoãn và lặp lại trong các ứng dụng ASP.NET. Không yêu cầu Dịch vụ Windows.

Trước tiên, hãy cài đặt gói thông qua NuGet. Nếu bạn có bất kỳ vấn đề gì, vui lòng xem hướng dẫn Quick Start trong tài liệu chính thức.

PM> Install-Package Hangfire 

Mở lớp OWIN Startup của bạn và thêm các dòng sau:

public void Configure(IAppBuilder app) 
{ 
    GlobalConfiguration.Configuration.UseSqlServerStorage("connection_string"); 

    app.UseHangfireDashboard(); 
    app.UseHangfireServer(); 
} 

Sau đó viết các phương pháp đó sẽ làm công việc lâu dài (tôi áp dụng thuộc tính để thực hiện phương pháp duy nhất tại một thời điểm) :

[DisableConcurrentExecution] 
public void LongRunning() 
{ 
    // Some processing stuff 
} 

và sau đó gọi một phương thức trong nền như lửa và-quên để đáp ứng người dùng ngay lập tức:

public ActionResult Perform() 
{ 
    BackgroundJob.Enqueue(() => LongRunning()); 
    return View(); 
} 

Nếu bạn muốn thông báo cho người dùng về hoàn thành công việc, hãy cân nhắc sử dụng SignalR và nối thêm phương thức LongRunning tương ứng.

+0

Giải pháp tuyệt vời. Cảm ơn khuôn khổ. – scottheckel

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