I have an issue with passing a long by value to a Task.
I have a list of ID's where I loop through each one, assign to a local variable then pass as a parameter to a new Task. I do not wait for the task to complete before looping round and processing the next ID. I keep an array of Tasks but this is irrelevant.
loop
long ID = list[index];
task[index] = Task.Factory.StartNew(() => doWork(ID));
end loop
If the list contained for example 100 and 200. I would want the first task called with 100 then the second task called with 200. But it does not, doWork receives 200 for both tasks so there is an issue when the value is copied.
I can demonstrate with some simple console code
class Program
{
static void Main(string[] args)
{
long num = 100;
Task one = Task.Factory.StartNew(() => doWork(num));
num = 200;
Console.ReadKey();
}
public static void doWork(long val)
{
Console.WriteLine("Method called with {0}", val);
}
}
The above code will always display
Method called with 200
I modified the code to wait for the task status to switch from WaitingToRun
static void Main(string[] args)
{
long num = 100;
Task one = Task.Factory.StartNew(() => doWork(num));
while(one.Status == TaskStatus.WaitingToRun)
{}
num = 200;
Console.ReadKey();
}
This improves things but not 100% proof, after a few runs I got Method called with 200
Also tried the following
while (true)
{
if (one.Status == TaskStatus.Running | one.IsCompleted == true)
break;
}
but again got 200 displayed.
Any ideas how you can guarantee the value passed to the task without waiting for the task to complete?
Any help/ suggestions appreciated Ade