using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public sealed class Foo
{
public int ID;
private static readonly Dictionary<int, Foo> Instances = new Dictionary<int, Foo>();
public static void FillInstances()
{
// here's some magic code to fill .Instances
}
public static void DoSomething()
{
var tasks = new Task[Instances.Count];
var i = 0;
foreach (var foo in Instances.Values)
{
var instance = foo; // just to break the reference
var task = Task.Factory.StartNew(instance.DoSomethingInternal);
tasks[i++] = task;
Logger.DebugFormat("translation: task #{0} = id {1}", task.Id, instance.ID);
}
using (var timer = new Timer(callback =>
{
Logger.DebugFormat("--------------------- {0}", DateTime.Now);
foreach (var task in tasks)
{
var taskInstance = task; // just to break the reference
Logger.DebugFormat("task #{0}: {1}", taskInstance.Id, taskInstance.Status);
}
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)))
{
Task.WaitAll(tasks);
Logger.Debug("ready");
}
}
private void DoSomethingInternal()
{
Logger.DebugFormat("DoSomethingInternal / task #{0} - id {1}", Task.CurrentId, this.ID);
}
}
应该明确说明:我正在调用静态方法DoSomething
来并行调用实例方法DoSomethingInternal
。
输出我的控制台是:
translation: task #1 = id 9
translation: task #2 = id 5
translation: task #3 = id 2
translation: task #4 = id 3
translation: task #5 = id 7
translation: task #6 = id 8
translation: task #7 = id 1
translation: task #8 = id 10
DoSomethingInternal / task #8 - id 10
DoSomethingInternal / task #7 - id 1
DoSomethingInternal / task #6 - id 8
DoSomethingInternal / task #5 - id 7
DoSomethingInternal / task #4 - id 3
--------------------- 12/01/2011 08:29:57
task #1: Running
task #2: Running
task #3: Running
task #4: RanToCompletion
task #5: RanToCompletion
task #6: RanToCompletion
task #7: RanToCompletion
task #8: RanToCompletion
--------------------- 12/01/2011 08:29:58
task #1: Running
task #2: Running
task #3: Running
task #4: RanToCompletion
task #5: RanToCompletion
task #6: RanToCompletion
task #7: RanToCompletion
task #8: RanToCompletion
--------------------- 12/01/2011 08:29:59
task #1: Running
task #2: Running
task #3: Running
task #4: RanToCompletion
task #5: RanToCompletion
task #6: RanToCompletion
task #7: RanToCompletion
task #8: RanToCompletion
显然,任务#1,#2,#3永远不会开始,但.Status
个实例的System.Threading.Tasks.Task
告诉我们它是Running
。
那么这里的问题是什么?
答案 0 :(得分:1)
我会说你在DoSomethingInternal
的某个地方遇到了死锁,你的输出看起来与我线性相当。
当我运行代码时,使用Console.WriteLine
作为两种记录器方法,输出为:
translation: task #1 = id 0
DoSomethingInternal / task #1 - id 0
translation: task #2 = id 1
translation: task #3 = id 2
DoSomethingInternal / task #2 - id 1
DoSomethingInternal / task #3 - id 2
DoSomethingInternal / task #4 - id 3
translation: task #4 = id 3
translation: task #5 = id 4
DoSomethingInternal / task #5 - id 4
DoSomethingInternal / task #6 - id 5
translation: task #6 = id 5
translation: task #7 = id 6
translation: task #8 = id 7
DoSomethingInternal / task #7 - id 6
DoSomethingInternal / task #8 - id 7
translation: task #9 = id 8
translation: task #10 = id 9
DoSomethingInternal / task #10 - id 9
DoSomethingInternal / task #9 - id 8
ready
我可以通过锁定DoSomething
和DoSomethingInternal
中的同一个对象来获得类似的输出,尽管在我的情况下它是第7个不能完成的。 在DoSomething
主题
ThreadPool