2

I have an async method being called from with Parallel.For code below. Now looking at the code it is pretty straight forward with the exception JsonParse class has an static method all it does is calls the web service to download json string and converts that to an PairResults object and returns.

The issue I am having is the Parallel.For loop never exits, I can clearly see the data is coming from the webcall "item.part1=data.value" all working fine, but updateAllResults never finishes. What am I doing wrong?

public void updateAllResults()
{ 
    Parallel.For(0, PairList.Count(), (i) =>
    {            
         var item = PairList[i];
         var data = (Parse.JsonParse<PairResults>
                             .getJsonString("http://localhost:22354/" 
                                                        + item.Original)).Result;
         item.part1 = data.value;
    }); 
}
2
  • 1
    It should finish, but it could take a long time depending on the number of items in PairList. That being said, consider making this truly async by using async (i) => and await without the .Result call. Commented Mar 14, 2014 at 11:41
  • Ah that worked like magic. changing the method to async (i) => was the answer. Commented Mar 14, 2014 at 11:43

2 Answers 2

5

This is an anti-patern for Parallel.For, because you're using it only to start async operations and block on them. This way, it will block a limited number of pool threads, and the actual level of parallelism may be much lower than if you were using tasks instead:

public void updateAllResults()
{
    var tasks = PairList.Select(async (item) => 
    {
        var data = await Parse.JsonParse<PairResults>
            .getJsonString("http://localhost:22354/" + item.Original).
            .ConfigureAwait(false);

        item.part1 = data.value;
    });

    Task.WaitAll(tasks.ToArray());
}

Also, your question is tagged with tag. Both Parallel.For and the above code will block your UI thread, if you use it in a WinForms app. The right solution would be to use Task.WhenAll:

public async Task updateAllResults()
{
    var tasks = PairList.Select(async (item) => 
    {
        var data = await Parse.JsonParse<PairResults>
            .getJsonString("http://localhost:22354/" + item.Original)
            .ConfigureAwait(false);

        item.part1 = data.value;
    });

    await Task.WhenAll(tasks.ToArray());
}

// button click handler
async void button_Click(object s, EventArgs e)
{
    this.button.Enabled = false;
    try
    {
        await updateAllResults()
    }
    finally
    {
        this.button.Enabled = true;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

Parallel.For blocks until all iterations have been executed or there is a break from the loop just like a regular for statement. Make sure that all the data has been downloaded. After that the Parallel.For should finish and consequentially the method too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.