4

いくつかの I/O Completion ポートが完了するのを待つ最善の方法を見つけようとしています。

このシナリオでは、MVC3 Web アプリを使用しているとしましょう。(私の理解では、ここで I/O Completion ポートを使用することをお勧めします。これにより、元のスレッドを 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 ? 私が使用しているデータ サービスは、一度に 1 つのレコードしか取得できません (これは私の制御を超えています)。これらの個々のクエリを並行して実行したいと考えています。

4

2 に答える 2

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
   }
于 2012-05-01T16:34:23.623 に答える
0

TPL の使用は簡単です。

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

Order GetOrder(int id) { ... }
于 2012-01-05T01:23:18.113 に答える