GTK + виджеты / окна (случайным образом) повреждены с помощью таймеров - PullRequest
1 голос
/ 09 апреля 2010

Недавно я реализовал прокрутку текста в области ограниченного состояния экрана, используя таймеры, повторяющиеся каждые 100 мс, и добавление некоторой простой строки.

Однако, после этой самой реализации, я пришел к выводу, что мой 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 ]

1 голос
/ 10 апреля 2010

Чтобы программировать на GTK с несколькими потоками, вы должны сделать пару вещей, чтобы сделать вашу программу поточно-ориентированной. Здесь - краткое объяснение с использованием C.

Я больше знаком с GTK в C, но я предполагаю, что он работает так же в GTK #. Поэтому вы должны вызывать GLib.Thread.Init() и Gdk.Threads.Init() в начале вашей программы, заключить в скобки ваш вызов Application.Run() с Gdk.Threads.Enter() и Gdk.Threads.Leave(), а также убедиться, что любые вызовы GTK и GDK в фоновых потоках ( not обработчики сигналов GTK) находятся между Gdk.Threads.Enter() и Gdk.Threads.Leave().

0 голосов
/ 08 июня 2010

Обратные вызовы System.Timers.Timer поступают из потока пула потоков, но объекты GTK могут быть безопасно доступны только из потока GTK. Я бы предложил использовать GLib.Timeout , который работает в потоке GTK.

...