首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

System.Threading.Timer 的有关问题 。

2012-09-22 
System.Threading.Timer 的问题在线等。。。System.Threading.Timer假如说这个timer每200ms执行一次A那么time

System.Threading.Timer 的问题 在线等。。。
System.Threading.Timer 
假如说这个timer每200ms执行一次A
那么timer启动后是每200ms申请一个新线程执行A
  还是就是在启动的时候申请一个新线程,然后以后的A都在这个线程里执行???




[解决办法]
首先看如下程序

C# code
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{    class Program    {        static void callback(Object param)        {            string id = Guid.NewGuid().ToString(); //放一个随机产生的id用来区分每个callback调用,为了让输出看得更清楚            for (int i = 0; i < 5; i++)            {                Console.WriteLine("{0} loop {1}", id, i);                System.Threading.Thread.Sleep(1000);            }        }        static void Main(string[] args)        {            System.Threading.Timer t = new System.Threading.Timer(callback, null, 0, 1000);            Console.Read();        }    }}
[解决办法]
这是程序开始运行的一个输出片段:
c86e4a56-5f4d-4be9-9752-9af0a1387529 loop 0
c86e4a56-5f4d-4be9-9752-9af0a1387529 loop 1
d4e6da32-5254-4bb9-9a11-a1cf25863aa7 loop 0
c86e4a56-5f4d-4be9-9752-9af0a1387529 loop 2
d4e6da32-5254-4bb9-9a11-a1cf25863aa7 loop 1
ab622f0b-7f8d-40b1-b74e-1722e51eb86a loop 0
c86e4a56-5f4d-4be9-9752-9af0a1387529 loop 3
4edd3e9d-1c2b-4e16-be09-4fefc38c230c loop 0
d4e6da32-5254-4bb9-9a11-a1cf25863aa7 loop 2
ab622f0b-7f8d-40b1-b74e-1722e51eb86a loop 1
c86e4a56-5f4d-4be9-9752-9af0a1387529 loop 4
4edd3e9d-1c2b-4e16-be09-4fefc38c230c loop 1
47ac0157-43a4-4224-b4b9-770721ebbb57 loop 0
d4e6da32-5254-4bb9-9a11-a1cf25863aa7 loop 3
ab622f0b-7f8d-40b1-b74e-1722e51eb86a loop 2
5b7f4baa-858d-430e-8ccf-bb0ee90de88e loop 0
4edd3e9d-1c2b-4e16-be09-4fefc38c230c loop 2
47ac0157-43a4-4224-b4b9-770721ebbb57 loop 1
35c7f4a4-a528-47d8-b0b9-5cc1d25c1089 loop 0
d4e6da32-5254-4bb9-9a11-a1cf25863aa7 loop 4
ab622f0b-7f8d-40b1-b74e-1722e51eb86a loop 3
5b7f4baa-858d-430e-8ccf-bb0ee90de88e loop 1
4edd3e9d-1c2b-4e16-be09-4fefc38c230c loop 3
47ac0157-43a4-4224-b4b9-770721ebbb57 loop 2
35c7f4a4-a528-47d8-b0b9-5cc1d25c1089 loop 1
5dbb47cf-3444-47bf-8c4c-9b5ea2a22941 loop 0
ab622f0b-7f8d-40b1-b74e-1722e51eb86a loop 4
5b7f4baa-858d-430e-8ccf-bb0ee90de88e loop 2
4edd3e9d-1c2b-4e16-be09-4fefc38c230c loop 4
47ac0157-43a4-4224-b4b9-770721ebbb57 loop 3
35c7f4a4-a528-47d8-b0b9-5cc1d25c1089 loop 2
5dbb47cf-3444-47bf-8c4c-9b5ea2a22941 loop 1
e143eda8-0790-49cb-a685-b9c2dab7573b loop 0
5b7f4baa-858d-430e-8ccf-bb0ee90de88e loop 3
70adbb9b-90c2-4924-90e9-31d53441efa1 loop 0
a42a5128-dd26-48fb-9d53-3dc2996dcad1 loop 0
35c7f4a4-a528-47d8-b0b9-5cc1d25c1089 loop 3
e143eda8-0790-49cb-a685-b9c2dab7573b loop 1
5b7f4baa-858d-430e-8ccf-bb0ee90de88e loop 4
47ac0157-43a4-4224-b4b9-770721ebbb57 loop 4
70adbb9b-90c2-4924-90e9-31d53441efa1 loop 1
5dbb47cf-3444-47bf-8c4c-9b5ea2a22941 loop 2
9cf82d63-25d9-441d-adee-828ad1874b5c loop 0
a42a5128-dd26-48fb-9d53-3dc2996dcad1 loop 1
35c7f4a4-a528-47d8-b0b9-5cc1d25c1089 loop 4
e143eda8-0790-49cb-a685-b9c2dab7573b loop 2
70adbb9b-90c2-4924-90e9-31d53441efa1 loop 2
5dbb47cf-3444-47bf-8c4c-9b5ea2a22941 loop 3
5edc9ca3-2715-48d4-bfb6-c90341b6a84c loop 0
9cf82d63-25d9-441d-adee-828ad1874b5c loop 1
a42a5128-dd26-48fb-9d53-3dc2996dcad1 loop 2
e143eda8-0790-49cb-a685-b9c2dab7573b loop 3
70adbb9b-90c2-4924-90e9-31d53441efa1 loop 3
5dbb47cf-3444-47bf-8c4c-9b5ea2a22941 loop 4
ada6dc4b-7774-4cd1-a202-3ed89a25955a loop 0
5edc9ca3-2715-48d4-bfb6-c90341b6a84c loop 1
9cf82d63-25d9-441d-adee-828ad1874b5c loop 2
a42a5128-dd26-48fb-9d53-3dc2996dcad1 loop 3
e143eda8-0790-49cb-a685-b9c2dab7573b loop 4
70adbb9b-90c2-4924-90e9-31d53441efa1 loop 4
ffb316ad-1aa2-443c-9b3f-9de9dbbbcfd2 loop 0


ada6dc4b-7774-4cd1-a202-3ed89a25955a loop 1
5edc9ca3-2715-48d4-bfb6-c90341b6a84c loop 2
9cf82d63-25d9-441d-adee-828ad1874b5c loop 3
a42a5128-dd26-48fb-9d53-3dc2996dcad1 loop 4
ffb316ad-1aa2-443c-9b3f-9de9dbbbcfd2 loop 1
9124b616-d923-4a49-94f5-7bf12ff01c55 loop 0
ada6dc4b-7774-4cd1-a202-3ed89a25955a loop 2
5edc9ca3-2715-48d4-bfb6-c90341b6a84c loop 3
9cf82d63-25d9-441d-adee-828ad1874b5c loop 4
ffb316ad-1aa2-443c-9b3f-9de9dbbbcfd2 loop 2
9124b616-d923-4a49-94f5-7bf12ff01c55 loop 1
858e2132-933c-405e-9a3a-def3da8f949f loop 0
ada6dc4b-7774-4cd1-a202-3ed89a25955a loop 3
5edc9ca3-2715-48d4-bfb6-c90341b6a84c loop 4
7ce11d51-fa1f-4517-9c49-3e05ec88cc79 loop 0
ffb316ad-1aa2-443c-9b3f-9de9dbbbcfd2 loop 3
9124b616-d923-4a49-94f5-7bf12ff01c55 loop 2
858e2132-933c-405e-9a3a-def3da8f949f loop 1
ada6dc4b-7774-4cd1-a202-3ed89a25955a loop 4
7ce11d51-fa1f-4517-9c49-3e05ec88cc79 loop 1
bdb14d26-2829-44f5-bb04-09fe5eb90a56 loop 0
ffb316ad-1aa2-443c-9b3f-9de9dbbbcfd2 loop 4
9124b616-d923-4a49-94f5-7bf12ff01c55 loop 3
858e2132-933c-405e-9a3a-def3da8f949f loop 2
7ce11d51-fa1f-4517-9c49-3e05ec88cc79 loop 2
bdb14d26-2829-44f5-bb04-09fe5eb90a56 loop 1
40712cdd-cf7f-4074-8b09-64f6ef1a3f9a loop 0
9124b616-d923-4a49-94f5-7bf12ff01c55 loop 4
858e2132-933c-405e-9a3a-def3da8f949f loop 3
7ce11d51-fa1f-4517-9c49-3e05ec88cc79 loop 3
bdb14d26-2829-44f5-bb04-09fe5eb90a56 loop 2
40712cdd-cf7f-4074-8b09-64f6ef1a3f9a loop 1
4f118828-90dd-499c-827b-197abf4125e1 loop 0
858e2132-933c-405e-9a3a-def3da8f949f loop 4
7ce11d51-fa1f-4517-9c49-3e05ec88cc79 loop 4
bdb14d26-2829-44f5-bb04-09fe5eb90a56 loop 3
40712cdd-cf7f-4074-8b09-64f6ef1a3f9a loop 2
4f118828-90dd-499c-827b-197abf4125e1 loop 1
283c1582-6f8b-4383-84f3-e7e8ddf244b3 loop 0
bdb14d26-2829-44f5-bb04-09fe5eb90a56 loop 4
40712cdd-cf7f-4074-8b09-64f6ef1a3f9a loop 3
4f118828-90dd-499c-827b-197abf4125e1 loop 2
283c1582-6f8b-4383-84f3-e7e8ddf244b3 loop 1
7d8bc8b7-90bc-4f7d-8cd6-305080c379b5 loop 0
40712cdd-cf7f-4074-8b09-64f6ef1a3f9a loop 4
4f118828-90dd-499c-827b-197abf4125e1 loop 3
283c1582-6f8b-4383-84f3-e7e8ddf244b3 loop 2
7d8bc8b7-90bc-4f7d-8cd6-305080c379b5 loop 1
2e8ba890-55d2-4f4c-8d61-e4986f3aef57 loop 0
...
如果你能看懂这个验证你问题的方法,并且以后此类问题可以不求人的话,那就善莫大焉了。
[解决办法]
困了。

给一个使用消息通知主线程,并且让主线程同步运行消息的例子。注意这个代码没有严格测试,只是给你点思路:(类似Control.Invoke)

C# code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace ConsoleApplication1{    class Program    {        static void callback(Object param)        {            lock (msg)            {                msg.Enqueue(OnTimer);            }            e.Set();        }        static void OnTimer()        {            string id = Guid.NewGuid().ToString();            for (int i = 0; i < 5; i++)            {                Console.WriteLine("{0} loop {1}", id, i);                Thread.Sleep(1000);            }        }        static Queue<Action> msg = new Queue<Action>();        static EventWaitHandle e =            new EventWaitHandle(false, EventResetMode.AutoReset);        static void Main(string[] args)        {                        Timer t = new Timer(callback, null, 0, 1000);            while (true)            {                List<Action> actions = new List<Action>();                lock (msg)                {                    while (msg.Count > 0)                    {                        actions.Add(msg.Dequeue());                    }                }                actions.ForEach(x => x());                e.Reset();                e.WaitOne();            }        }    }}
------解决方案--------------------


可以简单(用眼睛)测试一下:

C# code
using System;using System.Threading;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            System.Threading.Timer t = new System.Threading.Timer(delegate            {                Console.WriteLine("Timer {0}", Thread.CurrentThread.GetHashCode());                Thread.Sleep(5000);            }, null, 0, 200);            Console.WriteLine("主线程 {0}", Thread.CurrentThread.GetHashCode());            Console.ReadKey();        }    }}
[解决办法]
探讨
得到真相了,不过小失落了。我想在一个线程里(非主线程)每隔固定时间执行一次A,只能使Thread.Sleep()吗?

[解决办法]
System.Threading.Timer t = new System.Threading.Timer(callback, null, 0, 1000);
就是间隔调用事件
[解决办法]
我稍微加点注释,不是很复杂的

C# code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace ConsoleApplication1{    class Program    {        //我们在callback中不直接调用定时器处理函数,而是将要处理的函数作为委托放入队列中        static void callback(Object param)        {            lock (msg)            {                msg.Enqueue(OnTimer);            }            //激活主线程            e.Set();        }        //真正的定时器处理函数        static void OnTimer()        {            string id = Guid.NewGuid().ToString();            for (int i = 0; i < 5; i++)            {                Console.WriteLine("{0} loop {1}", id, i);                Thread.Sleep(1000);            }        }        //这个队列保存所有待处理的定时器函数的委托        static Queue<Action> msg = new Queue<Action>();        //定义一个线程事件,用来同步主线程和定时器线程        static EventWaitHandle e =            new EventWaitHandle(false, EventResetMode.AutoReset);        static void Main(string[] args)        {                        Timer t = new Timer(callback, null, 0, 1000);            //主程序不断循环            while (true)            {                //从队列中读取没有处理的定时器处理函数                List<Action> actions = new List<Action>();                lock (msg)                {                    while (msg.Count > 0)                    {                        actions.Add(msg.Dequeue());                    }                }                //这是关键,我们是在主程序里面调用定时器实际的处理函数,它之前被定时器放在了队列中                actions.ForEach(x => x());                //将线程事件对象重置,并且主线程休眠等待,直到队列中有新的要处理的函数                e.Reset();                e.WaitOne();            }        }    }} 

热点排行