开发者

GTK+ widgets/windows being (randomly) corrupted, with what seems to be timers

I have recently implemented a scrolling text across an area of limited screen estate using a timers repeating every 100ms, and some simple string appending.

However, after this very implementation, I have come to realise that my GUI is getting randomly bugged/corrupted after a certain while. That is to say that some widgets/windows become completely white, and eventually the entire GUI turns white and unclickable.

What is weird is that there is no error debug output at all.

Having said that, I am using Mono with GTK-Sharp for the application. Does anyone have an idea or a possible clue how and why this is happening?

If not, how can I further debug this properly?

Thanks, really appreciate it.

PS: Sometimes, it takes up to 1.5 hours for the thing to start corrupting, it has random timeframes for it to start happening.

This is my the code implemented that caused this issue:

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
   开发者_StackOverflow社区 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;
}


To program in GTK with multiple threads, you have to do a couple things to make your program thread-safe. Here is short explanation using C.

I'm more familiar with GTK in C, but I'm assuming it works the same in GTK#. So you have to call GLib.Thread.Init() and Gdk.Threads.Init() at the beginning of your program, bracket your call to Application.Run() with Gdk.Threads.Enter() and Gdk.Threads.Leave(), and also make sure any GTK and GDK calls in background threads (not GTK signal handlers) are between Gdk.Threads.Enter() and Gdk.Threads.Leave().


System.Timers.Timer callbacks come from a threadpool thread, but GTK objects can only safely be accessed from the GTK thread. I would suggest using GLib.Timeout, which runs on the GTK thread.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜