I helped create a background task system for an ASP.NET web site.
This is my root Task
Task.Factory.RunNew(RunTimer);
This is called from the root Task
.
private void RunTimer()
{
while (!cancellationToken.IsCancellationRequested)
{
var backgroundTasks = _tasks.Values.ToArray();
var tplTasks = new List<Task>();
foreach (var backgroundTask in backgroundTasks)
{
var newTask = new Task(() => backgroundTask.Run());
tplTasks.Add(newTask);
newTask.Start();
}
Task.WaitAll(tplTasks.ToArray());
for (int i = 0; i < NumberOfSecondsToWait &&
!cancellationToken.IsCancellationRequested; i++)
{
Thread.Sleep(new TimeSpan(0, 0, 1));
}
}
}
_tasks
is a ConcurrentDictionary<string, IBackgroundTask>
. For what ever reason, newTask
is executed 2 times on separate threads -- namely backgroundTask.Run()
is called twice. RunTimer
is only called once. NumberOfSecondsToWait
is 60. I've verified that tplTasks
only has 2 items in it.
Anyone have any idea?
This is because lambdas (in particular, the newTask
lambda) bind to variables, not values.
You need:
...
foreach (var backgroundTask in backgroundTasks)
{
var localBackgroundTask = backgroundTask;
var newTask = new Task(() => localBackgroundTask.Run());
...
}
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.