【发布时间】:2011-02-13 21:04:42
【问题描述】:
我一直在开发使用 HTTP 与客户端通信的自定义多线程服务器。为了创建新线程,我一直在使用 Task.Factory.StartNew() 方法。对于同步,我一直在使用 ManualResetEvent 对象。
下面是代码的精髓:
namespace ThreadTest {
class Program {
private readonly ManualResetEvent _event = new ManualResetEvent(false);
public void Start() {
for (int i = 0; i < 100; i++) {
int num = i;
Task.Factory.StartNew(() => {
Console.WriteLine("Task {0} Started", num);
_event.WaitOne();
});
}
}
static void Main(string[] args) {
var test = new Program();
test.Start();
Console.ReadLine();
}
}
}
在实际代码中,_event 对象最终会调用 Set 以释放等待的任务。
我遇到的问题是这段代码在我的开发机器上运行良好(它是双核的,每个核心有 2 个线程并使用 MS .NET 4 运行时)但在我的服务器上不起作用(即单核,每核 1 个线程并使用 Mono 2.8 运行时)。我的开发机器上的输出是:
Task 0 Started
Task 1 Started
Task 3 Started
Task 2 Started
Task 4 Started
Task 5 Started
...
虽然服务器输出是
Task 53 Started
我的问题是:我对 ManualResetEvent 或 Tasks 有什么误解?为什么TaskFactory继续在双核上做任务而不是在单核上?
更新:
我刚刚在我的双核(每核 1 个线程)mac 笔记本电脑上试了一下,我得到了输出
Task 97 Started
Task 1 Started
然后什么都没有。我还在我的开发机器(4 个线程)上使用 Mono 进行了尝试,并得到:
Task 99 Started
Task 2 Started
Task 98 Started
Task 0 Started
所以它看起来像 Mono 的一个错误。
【问题讨论】:
-
一个问题是您对所有任务使用相同的事件。一旦任何单个任务设置了事件,所有其他等待将立即结束。虽然这并不能解释为什么你的服务器只显示一个任务开始。
-
@Jim Mischel:是的,在真正的代码中,我有单独的事件。我只是不明白为什么,在单线程机器上,我一次只能启动 1 个任务。
标签: c# .net multithreading mono