GTK +小部件/窗口被(随机)损坏,似乎是计时器

时间:2010-04-09 18:25:28

标签: c# mono gtk gtk#

我最近使用每100毫秒重复一次的计时器在一个有限屏幕区域的区域内实现滚动文本,并添加了一些简单的字符串。

但是,在这个实现之后,我逐渐意识到我的GUI在一段时间后会随机出错/损坏。也就是说,一些小部件/窗口变成完全白色,最终整个GUI变白并且不可点亮。

奇怪的是,根本没有错误的调试输出。

话虽如此,我正在使用Mono和GTK-Sharp进行应用。有没有人有想法或可能的线索如何以及为何发生这种情况?

如果没有,我该如何进一步正确调试?

谢谢,真的很感激。

PS:有时候,事情开始腐败需要1.5小时,它有随机时间框架开始发生。

这是我实施的导致此问题的代码:

void ScrollSyncTo(object sender, System.Timers.ElapsedEventArgs e)
{
    //initial check if it fits nicely alr
    if (sync_to_full_txt.Length <= sync_to_max_char)
    {
        sync_to_timer.Stop();
        return;
    }

    //check for pause
    if (sync_to_pause >= 0)
    {
        sync_to_pause--;
        return;
    }

    //check direction
    int temp_psn;
    string temp_str;
    if (sync_to_direction)
    {
        temp_psn = sync_to_posn + 1;
        if (sync_to_full_txt.Substring(temp_psn).Length < sync_to_max_char)
        {
            sync_to_pause = sync_to_break_steps;
            sync_to_direction = false;
            sync_to_posn = sync_to_full_txt.Length - 1;
            System.GC.Collect();
            return;
        }
        else
        {
            temp_str = sync_to_full_txt.Substring(temp_psn, sync_to_max_char);
        }
    }
    else
    {
        temp_psn = sync_to_posn - 1;
        if (temp_psn + 1 < sync_to_max_char)
        {
            sync_to_pause = sync_to_break_steps;
            sync_to_direction = true;
            sync_to_posn = 0;
            System.GC.Collect();
            return;
        }
        else
        {
            temp_str = sync_to_full_txt.Substring(temp_psn - sync_to_max_char + 1, sync_to_max_char);
        }
    }

    //lets move it
    sync_to.Text = temp_str;
    sync_to_posn = temp_psn;
}

2 个答案:

答案 0 :(得分:1)

要使用多个线程在GTK中编程,您必须做一些事情来使程序线程安全。 Here是使用C的简短解释。

我对C语言中的GTK更熟悉,但我认为它在GTK#中的工作方式相同。因此,您必须在程序开头调用GLib.Thread.Init()Gdk.Threads.Init(),将Application.Run()Gdk.Threads.Enter()Gdk.Threads.Leave()的电话括在一起,同时确保后台线程中的GTK和GDK调用(不是 GTK信号处理程序)介于Gdk.Threads.Enter()Gdk.Threads.Leave()之间。

答案 1 :(得分:0)

System.Timers.Timer回调来自线程池线程,但GTK对象只能从GTK线程安全地访问。我建议使用GLib.Timeout,它在GTK线程上运行。