0

我想每隔 x 秒启动一次我的一些功能。但我不想等待任何功能完成,然后再启动该功能。假设我将计时器设置为 5 秒并开始functionX(),但 5 秒后functionX()没有完成 => 我想functionX()在新线程中重新开始。我还希望一组功能同时启动。

这就是为什么我认为我必须使用System.Threading.Timer并且Parallel让我们写一个简短的例子,我认为它应该是这样的:

class Program
    {
        private static System.Threading.Timer timer;
        private static int interval = 2000;

        static void Main(string[] args)
        {
            Console.WriteLine("go");
            Run();
            Console.WriteLine("end");
            Console.ReadKey();
        }

        private static void Run()
        {
            timer = new System.Threading.Timer(TimerCallback, null, 0, interval);
        }

        private static void TimerCallback(Object o) {
            Parallel.Invoke(() => FunctionA(), () => FunctionB(), () => FunctionC());
        }

        private static void FunctionA()
        {
            Console.WriteLine("A");
        }

        private static void FunctionB()
        {
            Console.WriteLine("B");
        }

        private static void FunctionC()
        {
            Console.WriteLine("C");
        }
    }

这可以吗?有什么建议么?即使这段代码有某种错误:我想问另一个关于我的输出的问题 - 如果我启动这段代码,我会得到类似这样的输出:

go
end
A
B
C
C
A
B
C
A
B
C
B
A

嗯。第一个输出go很好,但为什么是第二个,end为什么不A,,?这正常吗,输出 A、B、C 在第一个输出随机之后以某种方式出现?BC

下一个我不明白的问题:如果我删除该行 Console.ReadKey();,我看不到任何输出。

        static void Main(string[] args)
        {
            Console.WriteLine("go");
            Run();
            Console.WriteLine("end");
        }

我的意思是控制台正在启动,但在几毫秒后它关闭并且不再打开。但它应该会出现,因为我一次又一次地调用 A,B,C,所以一个新的控制台应该一次又一次地出现。有任何想法吗?谢谢

4

2 回答 2

2

main 方法在计时器创建后立即返回。这就是为什么end写得这么早。您的所有其余代码都在其他线程中执行。

您的计时器方法将三个作业发送到 .NET 并行扩展,这些扩展也在后台线程中执行作业。这就是为什么您看不到像 ABC 这样的有序输出,而是看到 ACB、BCA CBA 等。

因此,您有一个主线程、一个计时器后台线程和最多三个用于输出的工作线程(取决于您的 CPU)。

使Console.ReadKey()邮件线程等待键盘输入。在此期间,其他线程可以处理它们的工作。当您删除ReadKey调用时,您的程序在写入后立即结束,end并且不会等待其他线程完成。

更改您的代码不仅要编写开始、结束和 ABC,还要添加Thread.CurrentThread.ManagedThreadID到输出。然后你可以看到哪个线程运行哪个方法。

于 2012-08-22T15:33:47.690 回答
1

并行(和其他类似框架)不保证启动任务(线程)的执行顺序。如果你想保证执行顺序是''A,B,C'',你可以将它们放入一个函数中,并在线程中执行。

另一方面,从“Main”退出会中断正在运行的线程。典型的服务必须无限循环,直到达到退出条件(用户按下 ESC,接收信号,等等)。

由于您的线程在单个应用程序中运行,它们永远不会为它们的输出打开一个新的控制台窗口。

于 2012-08-22T15:36:19.247 回答