Изменение Gtk.Label.Text не всегда работает

У меня есть Gtk.Menu с 4 MenuItems. Следующий код выполняется каждую секунду, чтобы изменить Label.Text каждого MenuItem:

double d = new Random().NextDouble();

for (int i = 0; i < 4; i++)
{
    ((Label)((MenuItem)menu.Children[i]).Child).Text = d.ToString();
}

Я использую mono 2.10.8.1 с monodevelop 3.0.3.2 на ubuntu linux.

проблема

Проблема заключается в том, что не все ярлыки обновляются (иногда только первая и вторая, иногда только первая и последняя).

мой быстрый хак

Я могу решить эту проблему, разрешив потоку спящий 1 мс в каждом цикле:

for (int i = 0; i < 4; i++)
{
    ((Label)((MenuItem)menu.Children[i]).Child).Text = d.ToString();
    Thread.Sleep(1); // HACK !!!
}

вопросы

  • В чем причина этой проблемы?
  • Что было бы лучшим решением?

Ответ 1

Причиной этого является то, что вы обновляете интерфейс GUI за пределами основного потока GTK.

Основной поток GTK, которому принадлежит цикл событий, создается при вызове Gtk.Application.run.

Для обновления доступны несколько способов, вы можете попробовать Gtk.Application.Invoke,

 Gtk.Application.Invoke (delegate {
         double d = new Random().NextDouble();

         for (int i = 0; i < 4; i++) {
             ((Label)((MenuItem)menu.Children[i]).Child).Text = d.ToString();
         }
    });

Эта ссылка может представлять интерес.