2013-06-27 70 views
0

我在.net 2.0中使用C#在多線程應用程序上使用System.Timers。 每個線程都應該爲其定時器已用事件設置不同的時間間隔。計時器間隔在線程之間混合

這裏是我的情況:

我有一個根文件夾說:d:// ThreadingDemo /客戶端。現在,Clients文件夾可以包含n個文件夾。假設:1和2(在實際情況下等於客戶端數量)。在每個文件夾中都有一個xml配置文件(具有客戶特定的細節)。

配置爲1:

應用程序名:甲

TimeInterval所::5000

配置爲2:

應用程序名稱爲客戶端1

ClientCode應用支持:應用程序支持[R客戶端2

ClientCode:乙

TimeInterval所:2000

現在我的應用程序創建的線程多達客戶端的數量。在這種情況下,2個線程並在線程內設置時間間隔。
線程1與5000毫秒的間隔和線程2與2000毫秒

下面

是我上工作的代碼:

命名空間ConsoleApplication3

{

class Program 

{ 

    static string location = "D:\\ThreadingDemo\\Clients\\"; 
    public static System.Timers.Timer emailTriggerTimer = new System.Timers.Timer(); 
    static Double timeinterval; 

    static void Main(string[] args) 
    { 

     System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(location); 
     Thread th; 
     foreach (System.IO.DirectoryInfo g in dir.GetDirectories()) 
     { 
      th = new Thread(() => DoWork(g.Name)); //** Passes CLIENT NAME to the method 
      th.Name = g.Name; 
      th.Start(); 
      Console.WriteLine(" ThreadStart - ClientName : " + g.Name + " " + DateTime.Now); 
     } 
     Console.ReadKey(); 
    } 

    public static void DoWork(string fname) 
    { 

     emailTriggerTimer.Interval = GetsExecutionTimeFromConfigFile(); //** Gets Client specific FIRST EXECUTION TIME and converts to Time Interval 
     emailTriggerTimer.Elapsed += new System.Timers.ElapsedEventHandler((sender, e) => emailTriggerTimer_Elapsed(sender, e, fname)); 
     emailTriggerTimer.Enabled = true; 
     emailTriggerTimer.AutoReset = true; 
     emailTriggerTimer.Start(); 

     Console.WriteLine(" DoWork - ClientName :" + fname + " " + DateTime.Now); 
    } 

    private static object emailTriggerTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e, string fname) 
    { 
     emailTriggerTimer.Stop(); 
     emailTriggerTimer.Enabled = false; 

     Console.WriteLine(fname + " Elapsed " + DateTime.Now); 
     emailTriggerTimer.Interval = GetsTimeIntervalFromConfigFile(); //** Gets Client specific TIME INTERVAL 

     emailTriggerTimer.Start(); 
     emailTriggerTimer.Enabled = true; 
    } 
} 

}

我的代碼肯定是搞砸定時器的時間間隔,並設置最後的定時器時間間隔線程,即2000毫秒,這裏是下面的輸出:

的ThreadStart - CMDCMDLINE:1周27/06/2013 12時13分12秒

的ThreadStart - CMDCMDLINE:2 27/06/2013 12時13分12秒

DoWork的 - CMDCMDLINE:1個27/06/2013十二時13分12秒

DoWork的 - CMDCMDLINE:2 27/06/2013十二時13分12秒

CMDCMDLINE:1消逝27/06/2013 12: 13:13

CMDCMDLINE:2]經過27/06/2013 12點13分13秒

CMDCMDLINE:1消逝27/06/2013 12時13分15秒

CMDCMDLINE:2]經過27/06/2013 12:13: 15

CMDCMDLINE:1消逝27/06/2013 12點13分17秒

CMDCMDLINE:2]經過27/06/2013 12點13分17秒

CMDCMDLINE:1消逝27/06/2013 12:13:19

Clien TNAME:2]經過27/06/2013 12點13分十九秒

CMDCMDLINE:1消逝27/06/2013 12時13分21秒

CMDCMDLINE:2消逝27/06/2013 12時13分21秒

CMDCMDLINE:1消逝27/06/2013十二時13分23秒

CMDCMDLINE:2上經過27/06/2013十二時13分23秒

我非常新使用定時器線程的概念。我會很感激,如果有人建議如何設置每個線程的時間間隔分開。謝謝!

+2

您使用的是同一個定時器所有線程! –

+0

謝謝你指出。但是結果中的時間間隔仍然不合適。 – NewTechie

回答

0

這似乎適用於我。我通過一個簡單的改變重新審視了這一點。第一次執行不是由定時器設置的,而是通過允許線程進入睡眠狀態來完成的。定時器(第一次執行後)的時間間隔設置完美。下面的代碼:

類節目

{ 

    static string location = "D:\\ThreadingDemo\\Clients\\"; 
    static Double timeinterval; 
    public static System.Timers.Timer emailTriggerTimer; 
    static void Main(string[] args) 
    { 

     System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(location); 
     Thread th; 
     foreach (System.IO.DirectoryInfo g in dir.GetDirectories()) 
     { 
      th = new Thread(() => DoWork(g.Name)); 
      th.Name = g.Name; 
      th.Start(); 
      Console.WriteLine(" ThreadStart - ClientName :" + g.Name + " " + DateTime.Now); 
     } 
     Console.ReadKey(); 
    } 

    public static void DoWork(string fname) 
    { 

     Thread.Sleep(Convert.ToInt32(GetsExecutionTimeFromConfigFile()));//** Gets Client specific FIRST EXECUTION TIME and converts to Time Interval   

     emailTriggerTimer = new System.Timers.Timer(); 
     emailTriggerTimer.AutoReset = true; 
     emailTriggerTimer.Elapsed += new System.Timers.ElapsedEventHandler((sender, e) => emailTriggerTimer_Elapsed(sender, e, fname)); 
     emailTriggerTimer.Interval = GetsTimeIntervalFromConfigFile(); //** Gets Client specific TIME INTERVAL 
     emailTriggerTimer.Enabled = true; 

     emailTriggerTimer.Start(); 

     Console.WriteLine(" DoWork - ClientName :" + fname + " " + DateTime.Now); 
    } 

    private static void emailTriggerTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e, string fname) 
    { 

     Console.WriteLine("ClientName : " + fname + " Elapsed " + " " + DateTime.Now); 
    } 


} 
1

由於您爲所有線程使用單個計時器對象,因此每個線程的事件處理程序都會添加到該單個計時器中。因此,當該單個計時器對象的時間間隔到期時,將執行所有事件處理器。

解決方法是爲每個單獨的線程創建一個計時器對象。

就是這樣。

class Program { 
    static string location = "D:\\ThreadingDemo\\Clients\\"; 
    static Double timeinterval; 


    static void Main(string[] args) { 
     System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(location); 
     foreach (System.IO.DirectoryInfo g in dir.GetDirectories()) { 
      var th = new Thread(() => DoWork(g.Name)); //** Passes CLIENT NAME to the method 
      th.Name = g.Name; 
      th.Start(); 
      Console.WriteLine(" ThreadStart - ClientName : " + g.Name + " " + DateTime.Now); 
     } 
     Console.ReadKey(); 
    } 

    public static void DoWork(string fname) { 
     var emailTriggerTimer = new System.Timers.Timer(); 
     emailTriggerTimer.Interval = GetsExecutionTimeFromConfigFile(); //** Gets Client specific FIRST EXECUTION TIME and converts to Time Interval 
     emailTriggerTimer.Elapsed += new System.Timers.ElapsedEventHandler((sender, e) => emailTriggerTimer_Elapsed(sender, e, fname, emailTriggerTimer)); 
     emailTriggerTimer.Enabled = true; 
     emailTriggerTimer.AutoReset = true; 
     emailTriggerTimer.Start(); 

     Console.WriteLine(" DoWork - ClientName :" + fname + " " + DateTime.Now); 
    } 

    private static void emailTriggerTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e, string fname, System.Timers.Timer emailTriggerTimer) { 
     emailTriggerTimer.Stop(); 
     emailTriggerTimer.Enabled = false; 

     Console.WriteLine(fname + " Elapsed " + DateTime.Now); 
     emailTriggerTimer.Interval = GetsTimeIntervalFromConfigFile(); //** Gets Client specific TIME INTERVAL 

     emailTriggerTimer.Start(); 
     emailTriggerTimer.Enabled = true; 
    } 
} 
+0

而且,它工作與否? – Maarten

+0

第一個線程似乎以5秒的間隔工作。但第二個線程在2秒間隔(因爲它應該)並不總是 ThreadStart - ClientName:1 27/06/2013 13:40:11 ThreadStart - ClientName:2 27/06/2013 13:40:11 CMDCMDLINE:2]經過27/06/2013 13點四十分13秒 CMDCMDLINE:2]經過27/06/2013 13時40分15秒 CMDCMDLINE:1消逝27/06/2013 13時40分十六秒 客戶名稱:2已過期27/06/2013 13:40:21 // **此處爲5秒 客戶名稱:1已經過期27/06/2013 13:40:21 客戶名稱:1已過期27/06/2013 13:40:26 客戶名稱:2經過27/06/2013 13:40:31 // **這裏是10秒 – NewTechie

+0

查閱文檔http://msdn.microsoft.com/en-us/library/system.timers.timer。 elapsed.aspx。由於Elapsed事件被推送到線程池,確切的執行時間可能會有所不同。 – Maarten