Tutu
Tutu

Reputation: 33

Executing a list of tasks at one shot in C#

I am trying to execute a list of tasks at runtime. I want this to be an async operation. Each task is invoking a webservice and returning a response which i am adding to a List. When all the operations are completed, i will merge all into a single doc.

Here is my code. Currently it is executing as just sync calls only. I want them to be shot at one times.

List<XmlDocument> XmlResponse = new List<XmlDocument>();
XmlDocument xDocument = new XmlDocument();
ServiceRequest service = GetServiceRequest();
var tasks = new List<Task>();

Parallel.ForEach(service.IRN, x => 
{
    tasks.Add(Task.Factory.StartNew(() =>
    {
        XmlDocument xRequest = BuildServiceRequest(
            new ServiceRequest 
            {
                AccountNumber = service.AccountNumber, 
                MemberId = service.MemberId, 
                IRN = new List<string> { x }
            });
        Debug.Print("Service Call " + DateTime.Now.ToString("hh.mm.ss.ffffff"));
        XmlDocument xResponse = WebRequest.Submit(xRequest); // This is invoking service
        XmlResponse.Add(xResponse);
    }));
});

try
{
    Task.WaitAll(tasks.Where(x => x != null).ToArray());
    xDocument = PrepareServiceResponse();
    Debug.Print("Task Ends" + DateTime.Now.ToString("hh.mm.ss.ffffff"));
}

If I run this code now, the service is invoked synchronously. Can anyone suggest the way to shoot all calls at one time in tasks list?

Upvotes: 0

Views: 446

Answers (1)

samjudson
samjudson

Reputation: 56853

You seem to be creating a load of tasks INSIDE a Parallel ForEach loop. You don't need to do that, as the Parallel.ForEach handles the creation of the tasks for you.

Parallel.ForEach(service.IRN, x => 
{
    XmlDocument xRequest = BuildServiceRequest(
       new ServiceRequest 
        {
            AccountNumber = service.AccountNumber, 
            MemberId = service.MemberId, 
            IRN = new List<string> { x }
        });
    Debug.Print("Service Call " + DateTime.Now.ToString("hh.mm.ss.ffffff"));
    XmlDocument xResponse = WebRequest.Submit(xRequest); 
    XmlResponse.Add(xResponse);
});

That should do it. Once you get to the next line all tasks will have completed. However, depending on how many calls you are making, how many threads are used, and how long each call takes there is no guarantee that the responses will be in the same order as the IRN strings.

As an aside, you might get errors adding to the list. See these two questions for alternative solutions: Can we add new elements to a list using Parallel.ForEach()? or Is this use of Parallel.ForEach() thread safe?

Upvotes: 3

Related Questions