2012-07-15 25 views
5

Làm cách nào để thực hiện một phương thức không đồng bộ từ bên trong một phương thức điều khiển và trả về một HttpStatusCodeResult (200), mà không có đại biểu async kết thúc sớm việc thực thi của nó?Làm cách nào để thực thi đúng cách Phương thức Async trong ASP.net MVC?

Tôi đang làm việc trên một ứng dụng asp.net và một trong những hành động của tôi điều khiển nhà của tôi mất nhiều thời gian để chạy (10-30 giây). Tôi muốn trả về một HttpStatusCodeResult (200) và tiếp tục chạy hàm của tôi. Các functoin không cần phải trả lại bất cứ điều gì, nhưng nó vẫn không thực sự là một trường hợp cháy và quên kể từ khi tôi trả lại một phản ứng với máy chủ ngay lập tức với HttpStatusCodeResult.

Tôi đã thử sử dụng các đại biểu, nhưng có vẻ như một khi tôi trả lại mã trạng thái từ hành động, đại biểu sẽ ngừng thực thi. Một tùy chọn khác là tạo một dịch vụ cửa sổ nhưng điều đó sẽ giống như sử dụng bazooka để tiêu diệt một con ruồi. Tôi nhận được rất ít yêu cầu để tài nguyên và hiệu suất không phải là vấn đề trong trường hợp của tôi. Tôi nghe nói ThreadPool.QueueUserWorkItem là một tùy chọn, nhưng đó là lựa chọn phù hợp nhất cho trường hợp của tôi?

+0

Đây có thể là đặt cược tốt nhất của bạn: [Sử dụng bộ điều khiển không đồng bộ trong ASP.NET MVC] (http://msdn.microsoft.com/en-us/library/ee728598.aspx) –

+0

nhưng tôi nghĩ nó chỉ tối ưu hóa việc sử dụng của hồ bơi thread, tôi có nghĩa là tôi không thể trả lại mã httpstatus và tiếp tục thực hiện, kiểm tra _Converting Phương thức hành động đồng bộ để phương pháp hành động không đồng bộ_ phần –

Trả lời

1

Tạo lớp tĩnh quản lý hoạt động dài hạn này. Lớp này sẽ chịu trách nhiệm tạo chuỗi để thực hiện tác vụ và cũng cung cấp cách kiểm tra trạng thái của bất kỳ hoạt động nào đang diễn ra (tức là nếu nó vẫn đang trong quá trình thực hiện hoặc đã kết thúc và nếu có thì kết quả là gì).

Phương pháp Bộ điều khiển MVC của bạn sau đó sử dụng lớp này để thực hiện công việc và thông tin trạng thái hiện tại hoặc dữ liệu đã xử lý đã hoàn thành cho người dùng.

Something như thế này:

public ActionResult GetSomething(String id) { 
    TaskResult result = TaskClass.GetStatus(id); 
    if(result == null) { // the task has not been run, so start it up 
     TaskClass.StartNew(id); 
     return new View("PleaseWait"); 
    } else if(!result.IsFinished) { 
     return new View("PleaseWait"); 
    } else { 
     return View("Results", result); 
    } 
} 

public static class TaskClass { 
    private static Dictionary<String,TaskResult> _tasks; 
    public static TaskResult GetStatus(String id) { 
     // TODO: Make this code thread-safe 
     if(_tasks.ContainsKey(id)) return _tasks[id]; 
     return null; 
    } 
    public static void Start(String id) { 
     _tasks.Add(id, new TaskResult("Working")); 
     Thread thread = new Thread(SomeExpensiveOperation); 
     thread.Start(id); 
    } 
} 

Vào cuối SomeExpensiveOperation sẽ có mã mà đánh dấu sự TaskResult như xong.

+0

Điều này nghe có vẻ như nó có thể hoạt động. Phần duy nhất tôi không thể đoán được là: * ai vẫn đang nghe kết quả không đồng bộ sau khi phương thức điều khiển đã hoàn tất việc thực hiện? * –

+0

Không ai. Không cần phải là người nghe. Chỉ lưu trữ kết quả của hoạt động đã hoàn thành trong bộ nhớ cho đến khi máy khách yêu cầu. Xem câu trả lời cập nhật của tôi cho một ví dụ. Trong trường hợp này, tôi sử dụng một từ điển (lưu ý rằng mã của tôi không phải là chủ đề an toàn và bị lỗi với các lỗi, nhưng bạn sẽ có thể có được ý tưởng chung). – Dai

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