[英]System.Windows.Forms.Timer not firing
我想使用System.Windows.Forms.Timer
來確保在我正在創建的excel插件的UI線程上觸發事件。 我按如下方式構建計時器:
private System.Windows.Forms.Timer _timer;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Debug.WriteLine("ThisAddIn_Startup:" + Thread.CurrentThread.ManagedThreadId);
_timer = new System.Windows.Forms.Timer();
_timer.Tick += new EventHandler(TimerEventHandler);
_timer.Interval = 500;
}
計時器是由我正在使用的庫中的COM事件觸發的:
private void OnEvent()
{
_timer.Start();
}
然后我希望_timer
在_timer
時調用以下方法:
public void TimerEventHandler(object sender, EventArgs args)
{
_timer.Stop();
Debug.WriteLine("Tick: " + Thread.CurrentThread.ManagedThreadId);
}
據我所知,當我在Addin線程中創建計時器時,即使它是從另一個線程啟動的(在這種情況下是COM事件),它應該觸發它創建的線程,即插件線程。 但是,這不會發生。
我已經在我過去編寫的RTDServer
實現了這個確切的機制( 如Kenny Kerr所述 )並且它按預期工作,但是這個場景中的_timer
永遠不會_timer
。
我還閱讀了其他SO文章指出相同的行為,無法弄清楚我的插件設置有什么不同?
編輯:觸發OnEvent()方法。
我最初的意思是發布這個評論,但它變得太長了。
首先,你的線程結構對我來說有點混亂,就像你描述的那樣。 將Debug.WriteLine("OnEvent:" + Thread.CurrentThread.ManagedThreadId)
放在OnEvent
,讓我們知道您從調試輸出中看到的所有線程ID。
也就是說,規則是:
您應該在STA線程上創建WinForms的Timer
對象,並且線程應該在啟動之前配置為STA。
此線程可能是也可能不是主UI線程(創建主表單的位置),但仍應執行消息循環(使用Application.Run )以觸發計時器事件。 還有其他方法可以提取消息,但通常不會從.NET代碼中控制它們。
您應該在WinForms的Timer
創建的同一個線程上處理源代碼。 然后,您可以根據需要將這些事件“轉發”到另一個線程上下文(使用SynchronizationContext Send
或Post
),但我無法想到這種復雜性的任何原因。
在我看來,@ Maarten的答案實際上表明了正確的做法。
winforms計時器是一個控件,必須通過將其放在表單上來使用。 你永遠不會把它添加到控件集合中,所以我不希望它能正常工作。 文檔說明如下
實現以用戶定義的間隔引發事件的計時器。 此計時器已針對Windows窗體應用程序進行了優化,必須在窗口中使用。
因此,我建議您使用System.Timers.Timer類的實例。 這個類可以在任何地方使用。
請注意,上面使用的Tick事件由System.Timer.Timer類中的另一個名稱調用,即Elapsed-event 。
我還不明白為什么Forms.Timer沒有按預期運行,但下面的優秀文章詳細解釋了如何將工作編組到UI線程: http : //www.codeproject.com/Articles/31971/Understanding-的SynchronizationContext-部分-I
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.