任务并行库等待循环中的方法完成 (.NET 4.0)

Task Parallel library waiting for method in loop to finish (.NET 4.0)

想知道你是否可以提供帮助。

我有一个显示客户 EG 列表的列表视图(Customer1、Customer2、Customer3 等)

现在每个客户可以处理 1000 个订单,所以

我遇到的问题是我想等待 processcustomer 完成后再开始新的,并且 我不知道如何编码才能使我的 "ProcessCustomer" 在循环中完成才能继续下一个循环。

伪代码如下:

    public class form1
    {
        private void StartProcessingCustomer_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lvwCustomers.Items)
            {
                customerPresenter.ProcessCustomer(item.Tag as Customer);
            }
        }
    }


    public class CustomerPresenter
    {
            private void ProcessCustomer(Customer customer)
            {
                CustomerProcessor customerProcessor=new CustomerProcessor();
                customerProcessor.OrderProcessing += OnCustomerProcessing;
                customerProcessor.OrderProcessed += OnCustomerProcessed;
                customerProcessor.TaskCompleted += OnCustomerCompleted;

                customerProcessor.ProcessCustomer(customer);

            }
    }

     public class CustomerProcessor
    {
        public CustomerProcessor()
        {

        }

        public void ProcessCustomer(Customer customer)
        {
            //simplified version with psuedo code

            cancelToken = new CancellationTokenSource();
            var parOpts = new ParallelOptions();
            parOpts.CancellationToken = cancelToken.Token;
            parOpts.MaxDegreeOfParallelism = -1;

            const int index = 0;
            try
            {
                sw.Start();
                processResult.StartedAt = DateTime.Now;
                Task t1 = Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Parallel.ForEach(customer.Orders, parOpts, (order, loopState) =>
                        {
                            count = Interlocked.Increment(ref count);
                            ProcessOrder(order, count);
                        });
                    }
                    catch (OperationCanceledException)
                    {
                       //omitted code
                    }

                }, cancelToken.Token).ContinueWith(result => OnTaskCompleted(
                {
                   //omitted code
                }), new CancellationTokenSource().Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
            }

            catch (AggregateException ae)
            {
                //omitted code
            }
        }

        private void ProcessOrder(Order order, int index)
        {
            //we process the order here
        }

    }
    }

如果您将 ProcessCustomer 方法 return 设为 Task,您可以异步等待它完成:

public Task ProcessCustomer(Customer customer)
{
     return Task.Factory.StartNew(() => 
     {
            try
            {
                Parallel.ForEach(customer.Orders, parOpts, (order, loopState) =>
                {
                    count = Interlocked.Increment(ref count);
                    ProcessOrder(order, count);
                });
            }
            catch (OperationCanceledException)
            {
               //omitted code
            }

     }, cancelToken.Token).ContinueWith(result => OnTaskCompleted(
     {
       //omitted code
     }), new CancellationTokenSource().Token, TaskContinuationOptions.None,
         TaskScheduler.FromCurrentSynchronizationContext());
}

现在您可以:

//I'm assuming this is an event handler.
private async void SomeEventHandler(object sender, EventArgs e)
{
    foreach (ListViewItem item in lvwCustomers.Items)
    {
        await customerPresenter.ProcessCustomer(item.Tag as Customer);
    }
}

当您使用 .NET 4.0 时,您需要使用 Microsoft.Bcl.Async 才能使 async-await 可用。