时间:2019-03-17 标签:c#parallelIOCompletionPorts

发布于 2024-12-21 14:21:41 字数 1582 浏览 2 评论 0原文

我正在尝试找出等待一定数量的 I/O 完成端口完成的最佳方法。

对于这种情况,假设我正在使用 MVC3 Web 应用程序。 (我的理解是建议使用 I/O 完成端口,这样我就可以将原始线程返回到 IIS 来服务其他请求)

假设我有一个 ID 数组,并且我想从某个 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 ?我正在使用的数据服务一次只能获取一条记录(这超出了我的控制范围),并且我希望这些单独的查询并行运行。

I'm trying to figure out the best way to wait for some number of I/O Completion ports to complete.

For this scenario, let's say that I'm in a MVC3 web app. (My understanding is the use of I/O Completion ports here is recommended so I can return the original thread back to IIS to service other requests)

Lets say I have an array of IDs and I want to fetch an object for each ID 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's 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's ignore how this would be populated
   }

Should I be using DataServiceContext.BeginExecute Method? DataServiceContext.BeginExecuteBatch ? The data service I'm consuming can only get one record at a time (this is beyond my control) and I want these individual queries to run in parallel.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱你不解释 2024-12-28 14:21:41

这是我最终用于在 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
   }

This is the pattern I've ended up using for running a batch of async operations 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's ignore how this would be populated
   }
糖粟与秋泊 2024-12-28 14:21:41

使用 TPL 很容易。

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

Order GetOrder(int id) { ... }

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) { ... }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文