Parallel.For problem
Hello All
I am trying to create an application in which there are around 10 dll's each working sequentially. Now I want to make the app multi threaded . the application checks if it can find name of machine through interface and if it does it starts doing different tests on machine(computer). So , suppose listbox have 3 computer names , it will make entry in 1st table say id=1, name=server 1and move to check drivers on machine ....
to make it multithreaded this is what I am trying ......Parallel.For(0, listBox1.Items.Count - 1, delegate(int i) gbl.strComputer = listBox1.Items[i].ToString(); { Logs.Logging(gbl.logFilePath, " ", true); Logs.Logging(gbl.logFilePath, "Establishing Connection to......." + gbl.strComputer, true); Conn.fnConnect(gbl.strComputer, gbl.logFilePath); if (returnConnect == 0) // if able to connect start pulling the information { id = Machine_Information.InsertServerInformation(gbl.strComputer, gbl.logFilePath); if (id == 0) { Logs.Logging(gbl.logFilePath, "Processing FAILED on " + gbl.strComputer, true); Logs.Logging(gbl.logFilePath, " ", true); } else { Driver Information Logs.Logging(gbl.logFilePath, "Task 4 STARTED : Getting Driver Information", true); Driver_Information.InsertDriverInformation(gbl.logFilePath, gbl.strComputer, id); if (driverInfoCollector) Logs.Logging(gbl.logFilePath, "Task 4 Finished : Driver Information inserted in Driver Table", true); else { Logs.Logging(gbl.logFilePath, "Task 4 Failed. Some or All drivers are not written to database. ", true); #endregion }
Problem is After adding Parallel.for in the code , it inserts bad information. Sometimes , its just entering same information sometimes its not entering anything . When i try to step through the code , it waits at some lines indefinitely and next time it steps through ssamr line in very fast.
PLease let me know , what is the procedure of using this library to do something like :
if(listbox.item.count >0)
{
put information in 1st table
if(information inserted in 1st table )
{
use primary key of 1st table that is "id" as input in second dll and put information in 2nd table
use primary key of 1st table that is "id" as input in third dll and put information in 3rd table
use primary key of 1st table that is "id" as input in fourth dll and put information in 4th table
and so on ....................
}
go back to second item of list and try to put information in 1st table and use its id for other tables....
}Please let me know what exactly needs to be done here ?
Thanks
Varun
Answers
- Hey Varun,
Are you using an older version of Parallel Extensions like the June 2008 CTP? If so, I strongly suggest trying Visual Studio 2010 and .NET 4 Beta 2 (where everything is newer and better =)
Regarding guidance, I would start with the msdn documentation: http://msdn.microsoft.com/en-us/library/system.threading.tasks(VS.100).aspx. Also, here is a blog post on TaskScheduler and how it can be used in UI contexts: http://blogs.msdn.com/pfxteam/archive/2009/09/22/9898090.aspx.
HOpe this helps,
Danny- Marked As Answer byStephen Toub - MSFTMSFT, ModeratorTuesday, November 10, 2009 12:55 AM
- Proposed As Answer byStephen Toub - MSFTMSFT, ModeratorWednesday, November 04, 2009 4:35 AM
All Replies
- Hi Varun,
You capture the iteration variable 'i' in this line:
gbl.strComputer = listBox1.Items[i].ToString();
This is a common error due to how .NET captures state in closures. Try using a temporary variable:
int tmp = i;
gbl.strComputer = listBox1.Items[tmp].ToString();
That should fix the "same information everywhere" problem.
Also, this is a Windows Forms app, right? It's generally not recommended to call Parallel.For directly on the UI thread. That API implicitly joins (waiting for all iterations to complete), so it could render your UI unresponsive. Consider wrapping it in a Task or using Tasks directly.
Hope this helps,
Danny- Proposed As Answer byStephen Toub - MSFTMSFT, ModeratorFriday, October 30, 2009 9:59 AM
- Danny
Thanks a lot for replying to this.
Can you suggest a small example of using Task library ?
I will try your suggestion for tmp variable and let you know ....
Many thanks again!!
Varun - Hey Varun,
You mean for the second point, right? Wrapping a Parallel.For call in a Task is pretty straightforward. In the following, I also schedule a continuation to update UI components (using the UI thread):
var ui = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(() => { Parallel.For(...); }).ContinueWith(_ => { UpdateUIComponents(); }, ui);
However, do you expect your iterations to run for a long time? If so, I would opt for using Tasks and the LongRunning option.
Task[] tasks = new Task[listBox1.Items.Count]; for(int i=0; i<listBox1.Items.Count; i++) { tasks[i] = Task.Factory.StartNew(() => { ... }, TaskCreationOptions.LongRunning); } var ui = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.ContinueWhenAll(tasks, _ => { UpdateUIComponents(); }, ui);
Hope this helps,
Danny- Proposed As Answer byStephen Toub - MSFTMSFT, ModeratorSunday, November 01, 2009 8:30 PM
- Hello Danny
Once again , many thanks for suggesting code here . I have added the reference system.threading and using these statementsusing System.Threading; using System.Threading.Tasks;
Now when I use this code as suggested by you :
Task[] tasks = new Task[listBox1.Items.Count]; for(int i=0; i<listBox1.Items.Count; i++) { tasks[i] = Task.Factory.StartNew(() =>
I get an error :
Error 3 'System.Threading.Tasks.Task' does not contain a definition for 'Factory'
Error 8 'System.Threading.Tasks.TaskCreationOptions' does not contain a definition for 'LongRunning'
Seems very simple error but am i missing any reference here ?
Please suggest where can I read a good tutorial on task and task scheduler ?
Thanks
Varun - Hey Varun,
Are you using an older version of Parallel Extensions like the June 2008 CTP? If so, I strongly suggest trying Visual Studio 2010 and .NET 4 Beta 2 (where everything is newer and better =)
Regarding guidance, I would start with the msdn documentation: http://msdn.microsoft.com/en-us/library/system.threading.tasks(VS.100).aspx. Also, here is a blog post on TaskScheduler and how it can be used in UI contexts: http://blogs.msdn.com/pfxteam/archive/2009/09/22/9898090.aspx.
HOpe this helps,
Danny- Marked As Answer byStephen Toub - MSFTMSFT, ModeratorTuesday, November 10, 2009 12:55 AM
- Proposed As Answer byStephen Toub - MSFTMSFT, ModeratorWednesday, November 04, 2009 4:35 AM


