【问题标题】:Does System.Threading.Timer actually run in two different threads?System.Threading.Timer 实际上在两个不同的线程中运行吗?
【发布时间】:2016-12-17 03:52:34
【问题描述】:

下面的代码示例

using System.Threading;

namespace TimerApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Timer Application *****\n");
            Console.WriteLine("In the thread #{0}",     Thread.CurrentThread.ManagedThreadId); 

            // Create the delegate for the Timer type. 
            TimerCallback timerCB = new TimerCallback(ShowTime);

            // Establish timer settings. 
            Timer t = new Timer(
                timerCB,                // The TimerCallback delegate object. 
                "Hello from Main()",    // Any info to pass into the called method (null for no info). 
                0,                      // Amount of time to wait before starting (in milliseconds). 
                1000);                  // Interval of time between calls (in milliseconds). 

            Console.WriteLine("Hit key to terminate...");
            Console.ReadLine(); 
        }

        // Method to show current time... 
        public static void ShowTime(object state)
        {
        Console.WriteLine("From the thread #{0}, it is background?{1}: time is {2}, param is {3}", 
            Thread.CurrentThread.ManagedThreadId, 
            Thread.CurrentThread.IsBackground,
            DateTime.Now.ToLongTimeString(), 
            state.ToString()); 
        }
    }
 } 

产生以下输出

***** 定时器应用程序 *****

在线程 #1
点击键终止...
从线程 #4 来看,它是背景?是的:时间是晚上 10:37:54,参数是来自 Main() 的 Hello
从线程 #4 来看,它是背景?是的:时间是晚上 10:37:55,参数是来自 Main() 的 Hello
从线程 #5,它是背景?是的:时间是晚上 10:37:56,参数是来自 Main() 的 Hello
从线程 #4,它是背景?是的:时间是晚上 10:37:57,参数是来自 Main() 的 Hello
从线程 #5 来看,它是背景?是的:时间是晚上 10:37:58,参数是来自 Main() 的 Hello
从线程 #4 来看,它是背景?是的:时间是晚上 10:37:59,参数是来自 Main() 的 Hello
从线程 #5 来看,它是背景?是的:时间是晚上 10:38:00,参数是来自 Main() 的 Hello
...
按任意键继续 。 . .

System.Threading.Timer 是否一次使用多个线程进行回调?

【问题讨论】:

  • 回调是在线程池线程上进行的。关于线程池的隐含意义是,您永远不能假设它运行在池中的任何特定线程上。如你所见。
  • @Hans Passant 所以每个新的回调调用都使用线程池中的不同线程?
  • 您可以看到#4 连续使用了两次。所以你知道事实并非如此。它主要是随机的,取决于您的程序和 .NET Framework 中还发生了什么。使用 Debug > Windows > Threads 调试器窗口来获得洞察力。

标签: c# .net multithreading timer threadpool


【解决方案1】:

它利用线程池,使用它在每个时间间隔发现可用的第一个线程。计时器只是触发这些线程的触发。

void Main()
{
    System.Threading.Timer timer = new Timer((x) =>
    {
        Console.WriteLine($"{DateTime.Now.TimeOfDay} - Is Thread Pool Thread: {Thread.CurrentThread.IsThreadPoolThread} - Managed Thread Id: {Thread.CurrentThread.ManagedThreadId}");
        Thread.Sleep(5000);

    }, null, 1000, 1000);

    Console.ReadLine();
}

输出

07:19:44.2628607 - Is Thread Pool Thread: True - Managed Thread Id: 10
07:19:45.2639080 - Is Thread Pool Thread: True - Managed Thread Id: 13
07:19:46.2644998 - Is Thread Pool Thread: True - Managed Thread Id: 9
07:19:47.2649563 - Is Thread Pool Thread: True - Managed Thread Id: 8
07:19:48.2660500 - Is Thread Pool Thread: True - Managed Thread Id: 12
07:19:49.2664012 - Is Thread Pool Thread: True - Managed Thread Id: 14
07:19:50.2669635 - Is Thread Pool Thread: True - Managed Thread Id: 15
07:19:51.2679269 - Is Thread Pool Thread: True - Managed Thread Id: 10
07:19:52.2684307 - Is Thread Pool Thread: True - Managed Thread Id: 9
07:19:53.2693090 - Is Thread Pool Thread: True - Managed Thread Id: 13
07:19:54.2839838 - Is Thread Pool Thread: True - Managed Thread Id: 8
07:19:55.2844800 - Is Thread Pool Thread: True - Managed Thread Id: 12
07:19:56.2854568 - Is Thread Pool Thread: True - Managed Thread Id: 15

在上面的代码中,我们将线程设置为等待 5 秒,因此在打印到控制台后,线程会在完成执行并返回线程池之前再保持活动 5 秒。

无论如何,计时器都会每秒触发一次,它不会等待它触发的线程完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多