关于c#:更改Gtk.Label.Text并不总是有效

Changing Gtk.Label.Text does not always work

我有一个带有4个MenuItem的Gtk.Menu。每秒执行以下代码来更改每个MenuItem的Label.Text:

1
2
3
4
5
6
double d = new Random().NextDouble();

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

我在ubuntu linux上使用mono 2.10.8.1和monodevelop 3.0.3.2。

问题

问题在于并非所有标签都得到更新(有时只有第一个和第二个,有时只有第一个和最后一个)。

我的快速hack

我可以通过在每个循环中让线程hibernate1 ms来克服此问题:

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

问题

  • 此问题的原因是什么?
  • 有什么更好的解决方案?

  • 这是因为您正在GTK主线程之外更新GUI控件。

    当您调用Gtk.Application.run时,将创建拥有事件循环的主GTK线程。

    有几种方法可以更新,您可以尝试Gtk.Application.Invoke,

    1
    2
    3
    4
    5
    6
    7
     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();
             }
        });

    此链接可能很有趣。