C # parallel I / O ports IO

I am trying to find a better way to wait for a number of I / O completion ports to finish.

For this scenario, let's say I'm in the MVC3 web application. (My understanding of using I / O ports here is recommended, so I can return the original stream back to IIS to serve other requests)

Suppose I have an array of identifiers, and I want to get an object for each identifier from some network call.

What is the best way to parallelize this synchronous method?

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 ignore how this would be populated } 

I know it would start like this:

  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 ignore how this would be populated } 

Should I use the DataServiceContext.BeginExecute Method? DataServiceContext.BeginExecuteBatch ? The data service that I consume can only receive one record at a time (this is not in my control), and I want these separate requests to be executed in parallel.

+4
source share
2 answers

This is the pattern I used to run the asynchronous operations package inside 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 ignore how this would be populated } 
+2
source

Using TPL is easy.

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

Source: https://habr.com/ru/post/1386598/


All Articles