Attempting multi-window MonoGame, parent window hangs on communicating

So I decided a while back I’d make my own Qt/Forms alternative in MonoGame.

So far I’ve got a layout system similar to Qt/Forms, with buttons labels and other such widgets. I’ve come up with a solution to serialize windows to C# code that generates the windows, and currently I’m working on running windows asynchronously.

First I took a look at this code (post #5)

And I modified it to do what I wanted it to do. I give my created windows a delegate to the original Program.cs’s function to create new windows, and it was all working perfectly. Windows (called DWindows in my program) can create new Windows, albeit a little limited, and both windows are responsive.

At least up until this point, where I’m stuck at my limited understanding of multithreading.

An explanation to what’s going on here; This is my layout editor program, when I’m done with my project I will have this program bundled in an installer. Visual Studio will be able to open DWindow objects using this program, and my program will insert the new edited window into the current solution. That’s more or less how Qt and Visual Studio does it, and I believe things like the MonoGame Pipeline Tool work in a very similar way. On the top left, that’s my test layout, it’s very bugged and weird looking atm, but that’s not the issue. On the right is a property editing grid, similar to Visual Studio’s property editor when working with forms.

The problem is (and you can’t really tell in the gif) is that as soon as I try to read or modify any field property or method from the child window from the parent window, the parent window will hang until the user closes the child window.

The problem is best shown in DownUnder.UIEditor/Editor Tools/Widgets/PropertyLabel.cs => EditValue()

    private void EditValue(object sender, EventArgs args)
        Debug.WriteLine($"Editing value");
        var task = Task.Factory.StartNew(() =>
            DWindow bleh = ParentWindow.CreateWindow(EditWindow.GetType());
            return bleh;

        var test_task = Task.Factory.StartNew(() => 
            Boop boop = new Boop();
            return boop;

        // PROBLEM;

        // This doesn't cause this code to halt
        Debug.WriteLine($"test_task string = {test_task.Result.test_string_field}");

        // This causes the current code to halt, and not continue until
        // the created window is closed.
        Debug.WriteLine($"task.Result.test_string_field = {task.Result.test_string_field}");

        // Resizing the new window also hangs
        //task.Result.Dimensions = new Microsoft.Xna.Framework.Rectangle(0, 0, 50, 50);
        //Debug.WriteLine($"task.Result.Dimensions = {task.Result.Dimensions}");
        //Debug.WriteLine($"bleh type = {task.Result.GetType()}");
        Debug.WriteLine($"PropertyLabel: Done editting value.");

I would set of a Github, but before that, I think I’d rather see if an existing library like MonoGame Extended wants to integrate my library (once usable) into theirs. I’ve just uploaded a .zip file containing my project.

your second Debug.WriteLine actually relies on “task” being finished (there is no result until the task is finished, so it halts there. I guess .CreateWindow is a blocking function (otherwise you wouldn’t need a thread for it)

normally you have a window.closed event or something like that where you process the result.

In WinForms it would be a non-modal dialog which would have either a callback the parent dialog hooks into or a reference to the parent dialog where the child would update it

Non-Modal-Dialogs don’t necessarily need their own thread - because they run on the same message-loop as the parent window and as long as that message loop is not blocked they can run on the same thread (normally the UI thread)

That seems to be the case, thanks for the advice.

I don’t know why I assumed the task was actually completing. Knowing what you told me I saw that I had several botched tasks hanging.

I’ll have the child window update the parent window with a reference to itself I suppose. Thanks for the help, I’ve been caught on this (depressingly) for 4 days. :slight_smile: