2013-09-04 84 views
13

Tôi có một ứng dụng web phục vụ một API REST WCF cho JSON và một dịch vụ web ASMX. Ứng dụng này đã được khoảng một vài năm. Nó dựa trên ASP.NET 2.0, nhưng được nâng cấp lên .NET 4.0 một vài năm trước, và tôi vừa nâng cấp lên .NET 4.5 để có thể sử dụng khung công tác async mới.Có cách nào để xử lý async/chờ đợi sau dịch vụ ASMX không?

Đằng sau ứng dụng là một số dịch vụ kế thừa và tôi nhận ra rằng có tiềm năng lớn để tăng hiệu suất bằng cách đồng bộ hóa. Tôi đã thực hiện async tất cả các cách thông qua các ứng dụng, và tất cả mọi thứ đang làm việc hoàn hảo thông qua WCF REST API.

Quá trễ tôi phát hiện ra rằng API ASMX thất bại, tôi muốn các phương pháp như thế này:

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
async public Task<Trip> GetTrip(int tripid) 
{ 
    var t = await Trip.GetTrip(tripid); 
    return t; 
} 

sau đó tôi biết được rằng async/chờ đợi không được hỗ trợ trong ASMX ở tất cả, và tất cả mọi người khuyên để di chuyển đến WCF . Tôi không quá vui mừng về điều này. ASMX (thực sự là ba trong số đó) được nhồi với các phương thức khác nhau và có vô số người tiêu dùng API mà chúng tôi muốn tiếp tục phân phát từ API cũ.

Nhưng chúng tôi cần hiệu suất tăng lên! Có ai biết về một workaround vì vậy tôi có thể tiếp tục sử dụng async/chờ đợi đằng sau ASMX, nhưng lộ ASMX như trước?

+1

Bạn hiểu rằng async chỉ nhanh hơn trong những trường hợp đặc biệt? Cũng có thể chậm hơn. Nghiên cứu này đầu tiên. – usr

+0

có thể trùng lặp của [Gọi phương thức dựa trên nhiệm vụ từ ASMX] (http://stackoverflow.com/questions/24078621/calling-task-based-methods-from-asmx) – Paddy

Trả lời

13

Có thể thực hiện điều này, nhưng sẽ hơi khó xử. ASMX supports APM-style asynchronous methods và bạn có thể convert TAP to APM (tuy nhiên, lưu ý rằng ví dụ MSDN trên trang đó không truyền chính xác ngoại lệ).

Tôi có một ví dụ trên blog của tôi hiển thị how to wrap TAP implementations in APM (với tuyên truyền ngoại lệ giữ loại ngoại lệ chính xác nhưng mất ngăn xếp; xem ExceptionDispatchInfo để tuyên truyền hoàn toàn ngoại lệ chính xác). Tôi đã sử dụng điều này một thời gian khi WCF chỉ hỗ trợ APM. Một cách tiếp cận rất giống nhau nên làm việc cho ASMX.

Tuy nhiên, lưu ý rằng bạn sẽ have to target 4.5 (i.e., httpRuntime.targetFramework) for async/await to work as expected.

2

Nếu sự cố của bạn chỉ đơn giản là tích hợp phần trên cùng của logic không đồng bộ trong mã asmx, bạn có thể làm như đoạn mã sau.

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
public Trip GetTrip(int tripid) { 
    var trip = Trip.GetTrip(tripid).Wait(); 
    return trip; 
} 

Hãy nhận biết rằng nếu Trip.GetTrip() ném một ngoại lệ, bạn sẽ nhận được một AggregateException, và không phải là ngoại lệ, bạn sẽ nhận được nếu nó được chờ đợi ném ngoại lệ. Bạn có thể làm

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
public Trip GetTrip(int tripid) { 
    try 
    { 
    var trip = Trip.GetTrip(tripid).Wait(); 
    return trip; 
    } 
    catch(AggregateException ex) 
    { 
    throw ex.InnerException.First(); 
    }  
} 
+9

sử dụng .Wait() sẽ khiến cho WebMethod chặn , phủ nhận mọi lợi ích của việc không đồng bộ ngay từ đầu. –