线程.定时器停止在控制台应用程序

本文关键字:控制台 应用程序 定时器 线程 | 更新日期: 2023-09-27 18:04:26

我正在使用包含ID作为键和队列作为值的字典。我有一个线程写入队列,另一个线程从队列中读取,所以我需要使用。net 4.0中引入的concurrent结构。作为其中的一部分,我试图编写一个测试应用程序来填充队列,但我遇到了一个计时器在大约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; }
}

线程.定时器停止在控制台应用程序

很可能是计时器超出了作用域,正在被收集。在外部作用域声明计时器。即:

private Timer timer;
private void Run()
{
    ...
    timer = new Timer(WriteStuff, null, 0, 100);
}

而且,我认为你会发现BlockingCollectionConcurrentQueue更容易处理。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 });
    }
}