2011-12-15 43 views
4

我試圖找出等待一些I/O完成端口完成的最佳方法。c#並行IO完成端口

對於這種情況,假設我在一個MVC3網絡應用程序中。 (我的理解是使用I/O完成端口在這裏建議,這樣我可以返回到IIS的原始線程服務其他請求)

可以說我有一個ID數組,我想獲取一個對象來自某個網​​絡呼叫的每個ID。

並行化此同步方法的最佳方法是什麼?

public class MyController: Controller 
    { 
     public ActionResult Index(IEnumerable<int> ids) 
     { 
      ids.Select(id => _context.CreateQuery<Order>("Orders") 
            .First(o => o.id == id)); 
      DataServiceQuery<Order> query = _context.CreateQuery<Order>("Orders"); 
      return Json(query); 
     } 

     private DataServiceContext _context; //let's ignore how this would be populated 
    } 

我知道它應該像這樣開頭:

public class MyController: AsyncController 
    { 
     public void IndexAsync(IEnumerable<int> ids) 
     { 
      // magic here... 

      AsyncManager.Sync(() => AsyncManager.Parameters["orders"] = orders); 
     } 

     public ActionResult IndexCompleted(IEnumerable<Order> orders) 
     { 
      return Json(orders); 
     } 

     private DataServiceContext _context; //let's ignore how this would be populated 
    } 

我應該使用DataServiceContext.BeginExecute方法? DataServiceContext.BeginExecuteBatch?我正在使用的數據服務一次只能獲得一條記錄(這超出了我的控制範圍),我希望這些單獨的查詢能夠並行運行。

回答

0

使用TPL很容易。

public ActionResult Index(IEnumerable<int> ids) 
{ 
    var result = ids.AsParallel() 
     .Select(id => GetOrder(id)) 
     .ToList(); 
    return Json(result); 
} 

Order GetOrder(int id) { ... } 
+0

這將運行的線程數量的一些,將仍然阻止IIS線程。 – 2012-05-01 16:36:27

2

這是我已經結束了使用運行批處理操作異步裏面MVC3模式:

public class MyController: AsyncController 
    { 
     public void IndexAsync(int[] ids) 
     { 
      var orders = new Orders[ids.Length]; 
      AsyncManager.Parameters["orders"] = orders; 

      // tell the async manager there are X operations it needs to wait for 
      AsyncManager.OutstandingOperations.Increment(ids.Length); 

      for (int i = 0; i < ids.Length; i++){ 
       var index = i; //<-- make sure we capture the value of i for the closure 

       // create the query 
       var query = _context.CreateQuery<Order>("Orders"); 

       // run the operation async, supplying a completion routine 
       query.BeginExecute(ar => { 
        try { 
         orders[index] = query.EndExecute(ar).First(o => o.id == ids[index]); 
        } 
        catch (Exception ex){ 
         // make sure we send the exception to the controller (in case we want to handle it) 
         AsyncManager.Sync(() => AsyncManager.Parameters["exception"] = ex); 
        } 
        // one more query has completed 
        AsyncManager.OutstandingOperations.Decrement(); 
       }, null); 
      } 
     } 

     public ActionResult IndexCompleted(Order[] orders, Exception exception) 
     { 
      if (exception != null){ 
       throw exception; // or whatever else you might like to do (log, etc) 
      } 
      return Json(orders); 
     } 

     private DataServiceContext _context; //let's ignore how this would be populated 
    } 
+0

您是否在上下文的連接字符串上啓用了[`AsynchronousProcessing`](http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlconnectionstringbuilder.asynchronousprocessing.aspx)? – 2012-05-01 16:53:39