Click here to Skip to main content
14,975,219 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,

I want to call a method from for loop and combine the return type before presenting in the UI and method calling should in new thread so that I can reduce the execution time.

Below is the code
C#
private void Start_Click(object sender, EventArgs e)
        {
            string[] param = { "US", "UK", "CND" };
            ArrayList getData = new ArrayList();
            

            for (int i = 0; i < param.Length; i++)
            {
                //call in multithread
                getData.AddRange(GetData(param[i])); 
            }

            //marge all returns
            dg.DataSource = getData;
            
        }

        private ArrayList GetData(string param)
        {
            ArrayList returnData = new ArrayList();
            for (int i = 0; i < 10; i++)
            {
                returnData.Add(param + i.ToString());
            }
            Thread.Sleep(3000);
            return returnData;
        }
Posted
Updated 29-Sep-15 8:47am
v3
Comments
Sergey Alexandrovich Kryukov 29-Sep-15 14:34pm
   
First of all, why? Anyway, your Thread.Sleep is a huge abuse which defeat the whole purpose of threading. Aren't you trying to "synchronize" threads by waiting?
Another question is: why doing all that? Anyway, you can call any method in any thread, the problem is only synchronization or lack of it, and related race conditions, deadlocks and other bad things.
—SA
PrakashPaul 1-Oct-15 17:45pm
   
Thanks for your comment. my objective is, I have to present data from multiple servers, and at run-time as per user privilege I hit the databases(number of server).
to reduce the execution time I want to run the db function in multi-thread. so that I can save time.
but I want to wait till all started thread till not completed. and marge all output for next line of execution.

Hope I am able to clear my issue..
Actual code

[WebMethod]
public string GetCallDetails(string SearchXml, string[] countryList)
{
try
{
ArrayList alstOuput = new ArrayList();

System.Threading.Tasks.Parallel.For(0, countryList.Length, (i) =>
{
string strCountry = countryList[i];
//foreach (string strCountry in countryList)
//{
string strCountryConfig = string.Empty;
string strConnection = string.Empty;

try
{
strCountryConfig = "SQL_" + strCountry;
try
{
strConnection = AppConfigCache.Instance().GetConfigItem(strCountryConfig);
}
catch { }

if (!string.IsNullOrEmpty(strConnection))
{
string strXML = AppConfigCache.Instance().GetConfigItem("CORP_CONFIG_FOLDER");
Search objSearch = (Search)XMLManager.LoadFromXml(typeof(Search), SearchXml);
ArrayList CallDetailsList = objSearchFacade.GetCallDetails(objSearch, strConnection, strXML);
//lock (this._lockobject)
//{
alstOuput.AddRange(CallDetailsList);
//}
}
}
catch (Exception _exp)
{
LogManager.LogInformation(string.Format("GetCallDetails(), Error When Process DB Records : {0}", strCountryConfig));
LogManager.LogInformation(string.Format("GetCallDetails(), ERROR : {0}", _exp.ToString()));
}
//}
});
return XMLManager.ToXml(alstOuput);
}
catch (Exception e)
{
throw (e);
}
}

I take it the code you posted is just an example. If that is the case one way would be to use Parallel class.

First define an object variable on the class level
C#
object _lockobject = new object();

And try something like the following
C#
string[] param = { "US", "UK", "CND" };
System.Collections.ArrayList getData = new System.Collections.ArrayList();
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

// Sequential execution
watch.Reset();
watch.Start();
for (int i = 0; i < param.Length; i++) {
   getData.AddRange(GetData(param[i]));
}
watch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("Sequential execution took {0}", watch.Elapsed.ToString()));

// Parallel execution
watch.Reset();
watch.Start();
System.Threading.Tasks.Parallel.For(0, param.Length, (i) => {
   System.Collections.ArrayList partialresult;
   partialresult = GetData(param[i]);
   lock (this._lockobject) {
      getData.AddRange(partialresult);
   }
});
watch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("Parallel execution took {0}", watch.Elapsed.ToString()));
   
Comments
PrakashPaul 1-Oct-15 17:47pm
   
Thanks for the solution it is working partially, means in debug mode it is producing perfectly but in run it is not wait for all open task to complete.

my objective is, I have to present data from multiple servers, and at run-time as per user privilege I hit the databases(number of server).
to reduce the execution time I want to run the db function in multi-thread. so that I can save time.
but I want to wait till all started thread till not completed. and marge all output for next line of execution.

Hope I am able to clear my issue..

Actual code

[WebMethod]
public string GetCallDetails(string SearchXml, string[] countryList)
{
try
{
ArrayList alstOuput = new ArrayList();

System.Threading.Tasks.Parallel.For(0, countryList.Length, (i) =>
{
string strCountry = countryList[i];
//foreach (string strCountry in countryList)
//{
string strCountryConfig = string.Empty;
string strConnection = string.Empty;

try
{
strCountryConfig = "SQL_" + strCountry;
try
{
strConnection = AppConfigCache.Instance().GetConfigItem(strCountryConfig);
}
catch { }

if (!string.IsNullOrEmpty(strConnection))
{
string strXML = AppConfigCache.Instance().GetConfigItem("CORP_CONFIG_FOLDER");
Search objSearch = (Search)XMLManager.LoadFromXml(typeof(Search), SearchXml);
ArrayList CallDetailsList = objSearchFacade.GetCallDetails(objSearch, strConnection, strXML);
//lock (this._lockobject)
//{
alstOuput.AddRange(CallDetailsList);
//}
}
}
catch (Exception _exp)
{
LogManager.LogInformation(string.Format("GetCallDetails(), Error When Process DB Records : {0}", strCountryConfig));
LogManager.LogInformation(string.Format("GetCallDetails(), ERROR : {0}", _exp.ToString()));
}
//}
});
return XMLManager.ToXml<search>(alstOuput);
}
catch (Exception e)
{
throw (e);
}
}
Wendelius 1-Oct-15 23:23pm
   
I'm not sure if I understand your concern. All the operations inside the parallel for are executed before the loop ends. So perhaps the question is more of what operations you include inside the parallel block.
Try Task Parallel Library (TPL) with async & await functionality. Following article explains the best...

You can use (ContinueWhenAll and ContinueWhenAny) or (WhenAll and WhenAny)

Task Parallel Library and async-await Functionality - Patterns of Usage in Easy Samples[^]
   
Sorry for not answering your question; there is nothing to answer to. You need to understand different things: threading, parallelism, just the basics, first of all, the purpose. So far, you have no clue — please see my comment to the question. I would advise to start with this:
https://en.wikipedia.org/wiki/Race_condition[^],
https://en.wikipedia.org/wiki/Concurrency_control[^],
https://en.wikipedia.org/wiki/Synchronization_%28computer_science%29[^].

—SA
   
Comments
BillWoodruff 29-Sep-15 21:44pm
   
My vote of #1.

"Sorry for not answering your question; there is nothing to answer to."

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900