简体   繁体   中英

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

wonder if you can help.

I have a listview displaying a list of Customer EG (Customer1,Customer2,Customer3 etc..)

Now each customer can have 1000s of orders to process so

The problem I have is that I would like to wait for processcustomer to finish before starting with new one,and I dont know how to code it to make my "ProcessCustomer" in the loop to finish before can proceed with the next one.

Psuedo code below:

    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
        }

    }
    }

If you make your ProcessCustomer method return a Task , you can asynchronously wait for it's completion:

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());
}

Now you can:

//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);
    }
}

As you're using .NET 4.0, you'll need to use Microsoft.Bcl.Async to make async-await available.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM