【问题标题】:Multiple threads created for single Task为单个任务创建多个线程
【发布时间】:2011-06-17 15:11:55
【问题描述】:

我帮助为一个 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)); 
        } 
    } 
}

_tasksConcurrentDictionary&lt;string, IBackgroundTask&gt;。无论出于何种原因,newTask 在不同的线程上执行了 2 次——即 backgroundTask.Run() 被调用了两次。 RunTimer 只被调用一次。 NumberOfSecondsToWait 是 60。我已经验证 tplTasks 里面只有 2 个项目。

有人知道吗?

【问题讨论】:

  • 有什么问题?在我看来,_tasks 中的每个任务都会调用 backgroundTask.Run()。同样对于你应该使用的睡眠: System.Threading.Thread.Sleep(NumberOfSecondsToWait * 1000)
  • 它创建了 2 个线程。我正试图尽早阻止它。

标签: c# .net multithreading task-parallel-library


【解决方案1】:

这是因为 lambda(特别是 newTask lambda)绑定到变量,而不是值。

你需要:

...
foreach (var backgroundTask in backgroundTasks)
{
  var localBackgroundTask = backgroundTask;
  var newTask = new Task(() => localBackgroundTask.Run());
  ...
}
...

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多