我帮助创建了一个ASP.NET网站的后台任务系统。
这是我的根Task
Task.Factory.RunNew(RunTimer);这是从根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是一个ConcurrentDictionary<string, IBackgroundTask>。无论出于什么原因,newTask在不同的线程上执行两次--即backgroundTask.Run()被调用两次。RunTimer只调用一次。NumberOfSecondsToWait是60岁。我已经验证了tplTasks中只有2个项目。
有谁知道吗?
发布于 2011-06-17 23:22:54
这是因为lambda(特别是newTask lambda)绑定到变量,而不是值。
您需要:
...
foreach (var backgroundTask in backgroundTasks)
{
var localBackgroundTask = backgroundTask;
var newTask = new Task(() => localBackgroundTask.Run());
...
}
...https://stackoverflow.com/questions/6387887
复制相似问题