2010-08-24 28 views
5

Bên trong một asp.net MVC 2 điều khiển, tôi có đoạn mã sau:là nhân viên nền trong bộ điều khiển không đồng bộ?

using (BackgroundWorker worker = new BackgroundWorker()) 
         { 
          worker.DoWork += new DoWorkEventHandler(blah); 
          worker.RunWorkerAsync(var); 
         } 

Câu hỏi của tôi là: là mã async này, có nghĩa là nó sẽ khởi động một chủ đề mới và bộ điều khiển trả về quan điểm trong khi 'blah' là thực thi song song?

Nếu không, làm cách nào để đạt được các kết quả này?

Trả lời

7

Trong MVC 2 có một tính năng mới được gọi là AsyncController, đó là cách chính xác để thực hiện các cuộc gọi async trong MVC. Bộ điều khiển của bạn nên kế thừa từ AsyncController chứ không phải là bộ điều khiển. Sau đó, tên phương thức hành động chính của bạn phải có "Async" ở cuối. ví dụ, nếu bạn đã có một phương pháp hành động được gọi Blah(), bạn đặt tên trong BlahAsync() để thay thế và điều này sẽ được tự động được công nhận bởi khuôn khổ (và sử dụng BlahCompleted() cho callback):

public virtual void BlahAsync() 
{ 
    AsyncManager.OutstandingOperations.Increment(); 
    var service = new SomeWebService(); 
    service.GetBlahCompleted += (sender, e) => 
     { 
      AsyncManager.Parameters["blahs"] = e.Result; 
      AsyncManager.OutstandingOperations.Decrement(); 
     }; 
    service.GetBlahAsync(); 
} 

public virtual ActionResult BlahCompleted(Blah[] blahs) 
{ 
    this.ViewData.Model = blahs; 
    return this.View(); 
} 

Thông tin thêm trên AsyncController tại đây: MVC AsyncController

0

Tôi không chắc chắn điều này sẽ làm việc ra cho bạn (Tôi không nói rằng nó sẽ không , chỉ là tôi không chắc chắn ).

Câu trả lời ngắn gọn là , mã không đồng bộ. Nhưng để có được bất kỳ loại giá trị trả lại nào từ số BackgroundWorker, bạn cần xử lý sự kiện RunWorkerCompleted của nó.

Cơ chế cơ bản là để đặt một số giá trị vào e.Result tài sản trong trường hợp DoWork của bạn, và sau đó để lấy nó ra khỏi e.Result tài sản trong trường hợp RunWorkerCompleted của bạn (đảm bảo đầu tiên kiểm tra e.Error để xem nếu một ngoại lệ được ném vào DoWork).

Lý do tôi không chắc liệu nó có hiệu quả không là bạn đang sử dụng từ khóa using, đảm bảo rằng BackgroundWorker được xử lý ở cuối khối mã. Vì nó đang thực hiện công việc của nó một cách không đồng bộ, điều này có thể hoặc không thể ngăn cản bạn bao giờ có cơ hội xử lý RunWorkerCompleted. Tôi thực sự không chắc chắn - có thể ai đó khác biết?

0

Tôi nghĩ rằng có thể bạn sẽ gặp sự cố vì nó sẽ cố gắng xử lý công nhân trong khi chủ đề nền vẫn đang được sử dụng. Nếu không có gì khác, hành vi không thể đoán trước.

1

BackgroundWorker không thực sự là những gì bạn muốn ở đây: không có giao diện người dùng nào để cập nhật với tính năng gọi lại. Bạn chỉ muốn kích hoạt một mục công việc với một luồng thread thread và tiếp tục.

Phương thức ThreadPool.QueueUserWorkItem có thể phù hợp hơn ở đây hoặc sử dụng phương pháp tiếp cận song song Tác vụ mới: Task.Factory.StartNew(...).

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