Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoke GUI update calls in SetupDefaultSearch() descendants #3380

Merged
merged 1 commit into from
May 24, 2021

Conversation

DasSkelett
Copy link
Member

@DasSkelett DasSkelett commented May 23, 2021

Problem

With the restructuring to the search done in #3323 we added a call to SetupDefaultSearch(), which indirectly modifies GUI controls through other functions it calls.
As we all know, updating GUI components from another thread basically doesn't work.

In this case it manifests itself through freezes at the end of the repository update for some users.

Changes

Now ManageMods.Filter() and ManageMods.SetSearches(), both called in SetupDefaultSearch(), wrap every GUI-related work and call in a Util.Invoke().

The diff looks worse than the actual change 😄

I wonder if there's some static code analysis tool that can catch this? At least my IDE doesn't :/

I can't confirm the effectiveness of this patch, as my low core count tablet/laptop/convertible doesn't reproduce the hang/freeze (the runtime decides to run it all in a single thread there, I guess) and this only seems to affect Windows. I might dust off my Windows installation on my PC tomorrow to see if it experiences the bug.

Fixes #3379

@linuxgurugamer and @daantimmer, do you want to give this fix a try, after re-enabling the repo update on startup so it hits the critical code path?
If you click on the "Checks" tab in between the pull request header and body, there should be an "Artifacts" button on the right side, where you can download a ckan.exe built from this PR code.

@DasSkelett DasSkelett added Bug GUI Issues affecting the interactive GUI Pull request labels May 23, 2021
@DasSkelett DasSkelett requested a review from HebaruSan May 23, 2021 22:45
@HebaruSan
Copy link
Member

I wonder if there's some static code analysis tool that can catch this? At least my IDE doesn't :/

Yeah, that would be a dream come true. That's why I mentioned async/await in chat, but I don't think that quite maps properly to the GUI threading problem. Thanks for working on this, I'll review it shortly.

Copy link
Member

@HebaruSan HebaruSan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like what's needed. Would be wise to have confirmation from somebody who has experienced the issue, so I'm happy to wait a day or three for that.

@daantimmer
Copy link

daantimmer commented May 24, 2021 via email

@daantimmer
Copy link

I wonder if there's some static code analysis tool that can catch this? At least my IDE doesn't :/

That's why I mentioned async/await in chat

That won't help. You must update a GUI element in the GUI thread. Async/await does not do this for you. To update a GUI from a different worker thread you have to use Invoke. I always do: GuiElement.Invoke(() => expression);

@daantimmer
Copy link

@DasSkelett I can confirm this fixes my issue

@HebaruSan HebaruSan merged commit 549bf98 into KSP-CKAN:master May 24, 2021
@DasSkelett DasSkelett deleted the fix/repo-update-freeze branch May 24, 2021 18:37
@DasSkelett
Copy link
Member Author

DasSkelett commented May 24, 2021

An r/KSP Discord user just reported that they couldn't see the "clear search" cross:

The debug build from this PR fixed it for them as well, so it was also caused by the background thread GUI modifications.
Funny how different the effects can be.

@HebaruSan
Copy link
Member

HebaruSan commented May 24, 2021

You must update a GUI element in the GUI thread.

Right, the problem is that the cognitive load for doing this by hand across an entire application is unsustainable/impracticable. If we tagged all of our code that updates a GUI property directly as async, then at least we could potentially get a compile error if we try to call it from a background thread that isn't async. And we could easily check whether all our instances of DoWhatever().Result were using Invoke. I wonder if we could make our own [GUIOnly] attribute work somehow...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug GUI Issues affecting the interactive GUI Pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] CKAN "Not Responding" during/after loading.
3 participants