2011-12-17 68 views
0

我在C#中有一個函數,它首先將GUI DateTimePicker對象的值設置爲今天的日期(時間=午夜),然後執行其他操作。當通過GUI按鈕執行時,函數(DBIO_Morning)運行良好。但是,通過定時操作執行:設置DateTimePicker僅在定時動作觸發時關閉應用程序

private void SetupTimedActions() 
{ 
    ... 

    DateTime ref_morning = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 8, 16, 0); 
    if (DateTime.Now < ref_morning) 
     At.Do(() => DBIO_Morning(), ref_morning); 
    ... 
} 

它在第二行失敗:

private void DBIO_Morning() 
{ 
    DateTime date_current = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0); 
    DTPicker_start.Value = date_current; 
    ... 
} 

(At.Do對象就是從這裏開始的第三個答案:C# execute action after X seconds

+0

該代碼存在嚴重問題。隱藏線程是一個非常糟糕的主意。垃圾收集使其消失而無痕跡烘烤蛋糕。把它扔掉,只需使用Winforms Timer。不要隱藏它。 – 2011-12-17 15:12:19

回答

0

控件不是線程 - 安全,這意味着你不能從另一個線程調用控件的方法。您可以等到該控件的線程準備使用Control.Invoke來處理你的行動:

private void DBIO_Morning() 
{ 
    DateTime date_current = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, 0, 0); 
    Action setValue =() => DTPicker_start.Value = date_current; 
    if (DTPicker_start.InvokeRequired) 
     DTPicker_start.Invoke(setValue); 
    else 
     setValue(); 
} 
+0

我測試了你的建議並且它可以工作,但是我稍後在函數和定時器調用的其他函數中還有其他GUI調用。因此,我將嘗試通過實施下面的第二個解決方案來限制對定時功能的更改,而不是更改每個相關的GUI調用。不過謝謝! – 2011-12-17 14:47:18

+0

假設所有的控件都是在同一個線程中創建的,你可以在一個'Control.Invoke'調用中做所有的事情,你不必爲每個方法調用創建單獨的Action。我同意,使用另一個'Timer'可能更容易,並且避免了一個你並不需要的線程。祝你好運。 – hvd 2011-12-17 14:51:48

0

您正在試圖修改從另一個線程GUI元素,通過At.Do()隱式創建。見this thread

At.Do()中使用System.Windows.Forms.Timer而不是System.Threading.Timer可能會解決該問題。 (只需將new Timer(...)更改爲new System.Windows.Forms.Timer(...)即可。)

+0

從字面上看,只是將System.Threading.Timer改爲System.Windows.Forms.Timer沒有效果,因爲System.Windows.Forms.Timer沒有4個參數的重載。但是,一般來說,這可能是更方便的解決方案,因爲只有定時功能受到影響。你知道如何使'System.Windows.Forms.Timer'調用複製'new System.Threading.Timer(TimerCallback timer,Action action,int delayMilliseconds,int interval)'的功能嗎? – 2011-12-17 14:42:40

+0

[本頁](http://msdn.microsoft.com/zh-cn/library/xdh6857z.aspx)有一個示例。你創建一個'timer',設置它的'Tick'事件和'Interval'屬性,然後調用它的'Start'方法。你沒有這樣的單行構造函數,但它幾乎是一樣的。 – user1071136 2011-12-17 16:06:02

+0

我之前瀏覽過那個頁面,但是如何讓定時事件在特定時間每天一次(或一次性)發生?我可以計算運行時間和事件調度時間之間的時間差,並將其用作間隔,但是如何防止在該設置的間隔內重複執行事件? – 2011-12-17 17:00:30

相關問題