Постоянно вызывайте метод вместе с приложением GTKSharp - PullRequest
2 голосов
/ 06 марта 2020

Я создаю игру в реальном времени в GTKSharp (я знаю, не очень хорошая идея). У меня есть метод, который мне нужно постоянно вызывать, который обновляет мое игровое окно (изображения в некоторых кнопках), но я не могу понять, как.

Я попытался поместить метод в al oop и запустить l oop в другом потоке, кроме потока приложения.

  • Пробовал с Parallel.Invoke (хотя это просто запускает один поток за другим, он не может запустить их одновременно)

    public static void Main(string[] args) {
        Parallel.Invoke(() => RunGameLoop(), () => RunApp());
    }

    public void RunGameLoop(){
        while(runGame) { //runGame is a bool, I change it to false when I click a button in MyGameWindow
            MyGameWindow.UpdateButtons(); //MyGameWindow is a GTK.Window
        }
    }

    public void RunApp(){
        MyGameWindow.Show();
        Application.Run();
    }

  • Попробовал несколько различных способов разделения вещей в потоках (что привело к этой ошибке

GDK: ОШИБКА: /build/gtk+2.0-AoeliP/gtk+2.0-2.24.32/gdk/gdkregion-generic. c: 1110: miUnionNonO: утверждение не удалось: ( y1

, за которым следует пачка текста)


    public static void Main(string[] args) {
        Thread i = new Thread(new ThreadStart(RunGameLoop));
        Thread l = new Thread(new ThreadStart(RunApp));

        //I also tried with this
        //Thread i = new Thread(RunGameLoop);
        //Thread l = new Thread(RunApp);

        i.Start();
        l.Start();
    }

    public void RunGameLoop(){
        while(runGame) {
            MyGameWindow.UpdateButtons();
        }
    }

    public void RunApp(){
        MyGameWindow.Show();
        Application.Run();
    }

  • Я также пытался использовать задачи, а не потоки (также не работает)

    public static void Main(string[] args) {
        Task[] tasks = new Task[2];

        tasks[0] = Task.Run(() => RunGameLoop());
        tasks[1] = Task.Run(() => RunApp());

        Task.WaitAll(tasks);
    }

    public void RunGameLoop(){
        while(runGame) {
            MyGameWindow.UpdateButtons();
        }
    }

    public void RunApp(){
        MyGameWindow.Show();
        Application.Run();
    }


    public static void Main(string[] args) {
        Task t1 = Task.Factory.StartNew(() => RunGameLoop());
        Task t2 = Task.Factory.StartNew(() => RunApp());
        Task.WaitAll(tasks);
    }

    public void RunGameLoop(){
        while(runGame) {
            MyGameWindow.UpdateButtons();
        }
    }

    public void RunApp(){
        MyGameWindow.Show();
        Application.Run();
    }

Я потратил пару часов на эту проблему и, честно говоря, не знаю, могу ли я что-то неправильно понять о том, как работает многопоточность или как работает GTKSharp. Я думал о переводе проекта на что-то правильное, например, Unity, но я потратил много времени на изучение GTKSharp.

Я использую Monodevelop 7.8.4 (сборка 2), и проект GTK # 2.0 Project.

Редактировать: После большого количества поиска решений я натолкнулся на следующее: Как мне получить доступ к GUI (GTK) из многопоточности?, Итак, то, что я пытался сделать, было обречено с самого начала. Спустя еще немного времени, я обнаружил следующее: Winforms - вызов метода в другом потоке , который предназначен для WinForms, GTK-эквивалентом является предположительно GLib.Timeout, который я также не смог заставить работать.

Редактировать 2: После долгих раздумий, я думаю, это совершенно невозможно в GTK #. Мне придется изменить работу моей программы.

...