我正在使用包含ID作为键和队列作为值的字典。我有一个线程写入队列,另一个线程从队列中读取,所以我需要使用.NET 4.0中引入的并发结构。作为其中的一部分,我试图编写一个测试应用程序只是为了填补队列,但我遇到了一个问题,计时器在大约10秒后停止。我真的不明白为什么没有什么可以捕捉,没有错误信息或任何东西给我一个可能是错误的提示。
有人可以向我解释为什么计时器在大约10秒后停止?我在两台不同的计算机上试过这个(使用Visual Studio 2012,但使用的是.NET Framework 4.0)。
class Program {
private readonly ConcurrentDictionary<int, ConcurrentQueue<TestObject>> _pipes =
new ConcurrentDictionary<int, ConcurrentQueue<TestObject>>();
static void Main() {
Program program = new Program();
program.Run();
Console.Read();
}
private void Run() {
_pipes[100] = new ConcurrentQueue<TestObject>();
_pipes[200] = new ConcurrentQueue<TestObject>();
_pipes[300] = new ConcurrentQueue<TestObject>();
Timer timer = new Timer(WriteStuff, null, 0, 100);
}
private void WriteStuff(object sender) {
for (int i = 0; i < 5; i++) {
foreach (KeyValuePair<int, ConcurrentQueue<TestObject>> pipe in _pipes) {
pipe.Value.Enqueue(
new TestObject { Name = DateTime.Now.ToString("o") + "-" + i });
}
i++;
}
Console.WriteLine(DateTime.Now + "added stuff");
}
}
internal class TestObject {
public string Name { get; set; }
public bool Sent { get; set; }
}
答案 0 :(得分:5)
最有可能的是,计时器超出范围并被收集。在外部范围声明计时器。那就是:
private Timer timer;
private void Run()
{
...
timer = new Timer(WriteStuff, null, 0, 100);
}
此外,我认为您会发现BlockingCollection
比ConcurrentQueue
更容易使用。 BlockingCollection
围绕并发集合包装了一个非常好的API,使得在删除事物时更容易在队列上执行非繁忙等待。在其默认配置中,它使用ConcurrentQueue
作为后备存储。您只需使用ConcurrentQueue
替换代码中的BlockingCollection
,然后从调用Enqueue
更改为调用Add
即可。如:
for (int i = 0; i < 5; i++)
{
foreach (var pipe in _pipes)
{
pipe.Value.Add(
new TestObject { Name = DateTime.Now.ToString("o") + "-" + i });
}
}