我在我的多線程應用程序中使用了一些System.Threading.Timer(s)
(實際上有三個這樣的定時器),但是,儘管它工作得很好,但我感覺我做錯了,並且會消耗不必要的資源。實際上,我在做什麼是這樣的:System.Threading.Timer - 我使用它的權利?
在我的應用程序的主窗口(WPF窗口,但不認爲它的問題這麼多),我打開三個線程。
- 在每一個這三個線程
,我初始化和啓動三個定時器
,我使用三種不同的線程來做到這一點的原因是因爲我記得我讀過某處(無法找到位置),當我啓動System.Threading.Timer
時,我不能再使用當前線程(例如線程會在Timer啓動時以某種方式停止)。
現在,我測試了下一個簡單的應用程序,並且Timer和啓動它的線程之間似乎沒有衝突。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
System.Threading.Timer _t1, _t2, _t3;
private void Form1_Load(object sender, EventArgs e)
{
_t1 = new System.Threading.Timer(new TimerCallback(_t1Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(15));
_t2 = new System.Threading.Timer(new TimerCallback(_t2Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(35));
_t3 = new System.Threading.Timer(new TimerCallback(_t3Run),
null, TimeSpan.Zero, TimeSpan.FromMilliseconds(150));
for (int i = 1; i <= 5000; i++)
{
Console.WriteLine("Writting on main form " + i);
}
}
void _t1Run(object State)
{
_t1.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 1");
_t1.Change(TimeSpan.FromMilliseconds(15), TimeSpan.FromMilliseconds(15));
}
void _t2Run(object State)
{
_t2.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 2");
_t2.Change(TimeSpan.FromMilliseconds(35), TimeSpan.FromMilliseconds(35));
}
void _t3Run(object State)
{
_t3.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
Console.WriteLine("running 3");
_t3.Change(TimeSpan.FromMilliseconds(150), TimeSpan.FromMilliseconds(150));
}
}
那麼,我可以在主窗口(或我需要單獨的線程)上啓動所有三個定時器嗎?有人可以證實這不會導致問題(因爲在我測試過的應用程序中,它似乎沒有任何問題)?
編輯: 三個定時器有不同的目的,他們兩個確實有一些用戶界面的交互(一個主窗口和其他與二級窗口交互 - 第三做只是一些後臺操作),但我不使用System.Windows.Forms.Timer
的原因是計時器進行了大量操作,如果我要在主線程上執行所有這些操作,那麼實際上會阻止所有GUI交互(我在一段時間內調用這些計時器線程100-200毫秒,所以想象...)。 這就是我該怎麼辦,從由定時器稱爲線程的GUI交互的例子:
MainWindow.ThisInstance.TitleLabel.Dispatcher.BeginInvoke((Action)(() => UpdateMainWindow_TimeLabel(TimeLabelValue)));
最好給你的答案解釋。事實上,這些計時器存在不同的目的。 – Dennis
我編輯並給出了一些解釋。 – TheQuestioner
@nhrobin,好吧,做下一個技巧它告訴我標籤在GUI線程中被更新: 'MainWindow.ThisInstance.TitleLabel.Dispatcher.BeginInvoke((Action)(()=> UpdateMainWindow_TimeLabel(TimeLabelValue)) ); ' 'Private static void UpdateMainWindow_TimeLabel(String TimeLabelValue) Console.WriteLine(「Thread thisCurrentThread.Name」); MainWindowInstance.TimeLabel.Content = TimeLabelValue; }' – TheQuestioner