Вопрос

I have a function in C# which, at the outset, sets the value of a GUI DateTimePicker object to today's date (time = midnight), then does other stuff. When executed via GUI button, the function (DBIO_Morning) runs fine. But, executed via timed action:

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);
   ...
}

it fails in the second line:

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 object is from the third answer here: C# execute action after X seconds )

Это было полезно?

Решение

Controls are not thread-safe, meaning you must not call a control's methods from another thread. You can wait until the control's thread is ready to handle your action using 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();
}

Другие советы

You are trying to modify GUI elements from another thread, created implicitly by At.Do(). See this thread.

Using System.Windows.Forms.Timer in At.Do() instead of System.Threading.Timer will probably solve the problem. (Just change new Timer(...) to new System.Windows.Forms.Timer(...).)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top