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.