Click here to Skip to main content
15,894,410 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
I'm creating a new task to grab some information using this line of code:

Task.Factory.StartNew(Sub() ReadOPCData(TimerToRead), TaskCreationOptions.AttachedToParent)


It works but the variable being passed to the subroutine (TimerToRead) seems to get changed by the routine that created the task ... and then the value output within the task ends up being wrong.

If I don't use a task and simply call it as a subroutine it works exactly as expected. The results output are correct and the variable doesn't get changed. However I want to use a task because the calling routine is time sensitive so I want to use other threads as much as possible so I can return to processing my clock ticks and keeping them accurate.

Here is some code from the called routine that isn't working when it's called as a task: (This is just testing code AddErrItem will actually display errors in the future, right now it's just an output location)

DispText = "Timer: " & CurTimerToRead.ToString
If Me.InvokeRequired Then
    Me.Invoke(System.Delegate.CreateDelegate(GetType(myInvokedMethod), Me, "AddErrItem"), New Object() {DispText})
Else
    AddErrItem(DispText)
End If


Any suggestions greatfully appreciated. I'm very new to multithreaded programming and fairly new to VB.Net
Posted
Comments
Sergey Alexandrovich Kryukov 7-Sep-11 19:46pm    
What's "not working"?
--SA
BHort 8-Sep-11 10:07am    
When I run it as a subroutine I get:

Timer: 1
Timer: 1
Timer: 1
Timer: 2
Timer: 1
Timer: 1
Timer: 2
etc.

which is correct. When I run it as a task I get:

Timer: 1
Timer: 1
Timer: 1
Timer: 2
Timer: 2
Timer: 2
Timer: 1
etc.

Or various other similar wrong values for what should be displayed.

Timer 1 is going 100 times per second. Timer 2 is 40 times per second. Timer 3 is every 1/10th of a second (not that I've shown the third timer in my sample)

When you are using threads, the output can be non deterministic because of OS and processor scheduling.

Your program is working perfectly fine, if however the output order is not what you want, you will have to do something else.
 
Share this answer
 
Comments
BHort 12-Sep-11 10:04am    
I understand the non-deterministic nature of threads but the issue that's causing me to question that being the source of the problem is the fact that the total number of "1"s and "2"s aren't correct. If you notice in my "correct" output I have 5 "1"s and 2 "2"s ... the incorrect showing 4 and 3 respectively. The quantity of each output isn't correct ... which is where my feeling like the variable is getting changed is coming from.
Mehdi Gholam 12-Sep-11 10:12am    
Are the counts different in total after finishing?
BHort 12-Sep-11 10:12am    
Part of my concern is coming from the fact that I'm using a component that uses a multimedia timer to implement a timer component that can generate "tics" with a frequency lower than every 15 ms. It seems to work great when I use it and call my routine as a subroutine but not when I call it as a task ... and I'm wondering if the transfer of the variable into the task is getting interrupted by another "tic" and hence the variable gets changed mid process.
Is there a way to ensure the launching of the thread is atomic? Another thought I had was to put my values into an ArrayList using a Monitor.Enter/Exit pair and pulling them off again within the task. I might not guarantee that execution 1 gets value 1 (because of the non determinism) but I can ensure that for n values there will be n calls and thus all the values will be processed.
Does that sound like a plausible option? Again, I'm fairly new at VB.Net multithreading so I'm open to being told I'm out to lunch ...
BHort 12-Sep-11 11:59am    
No, the counts aren't different in the total number of counts, just in the values that should be displayed.
I've got a very small project that I've created to demonstrate the problem ... but it requires the multimedia timer DLL that was part of the article here:

The Multimedia Timer for the .NET Framework
Mehdi Gholam 12-Sep-11 12:05pm    
Ah great! then your code is working fine and you don't have the variable changing. The problem is the process scheduler. Unfortunately you can't do anything about that, as the OS and CPU are handling the task switches.
The solution that worked (likely not the only, and perhaps not even the best solution) was to create Monitor.enter() and Monitor.exit() blocks in the calling routine and in the called sub-task ... and put the parameter into a queue in the calling routine and pull it out in the sub-task.
The non deterministic nature of the threads was visible in the results but the results had exactly the number of each timer as was expected and the threads executed within the time restrictions that were required.
Thanks Mehdi for all your help and comments. While they didn't directly provide the solution, they were certianly appreciated.
 
Share this answer
 

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