C
C#15mo ago
Florian Voß

❔ WPF UI freezes while operation

private async void OnContactSearch(object sender, EventArgs e)
{
string search = ContactSearchInput.Text;
TryGetSelectedFilter(out RadioButton selectedFilter);
var filter = selectedFilter?.Content as string ?? "";
TryGetSelectedSort(out RadioButton selectedSort);
var sort = selectedSort?.Content as string ?? "";
if (search.Equals("suchen", StringComparison.OrdinalIgnoreCase)) search = "";
_columnMappingUIToDb.TryGetValue(filter, out filter);
_columnMappingUIToDb.TryGetValue(sort, out sort);
DataTable contacts = await Task.Run(() => FilterContactsFromMemory(search, filter, sort));
DisplayContacts(contacts);
}
private async void OnContactSearch(object sender, EventArgs e)
{
string search = ContactSearchInput.Text;
TryGetSelectedFilter(out RadioButton selectedFilter);
var filter = selectedFilter?.Content as string ?? "";
TryGetSelectedSort(out RadioButton selectedSort);
var sort = selectedSort?.Content as string ?? "";
if (search.Equals("suchen", StringComparison.OrdinalIgnoreCase)) search = "";
_columnMappingUIToDb.TryGetValue(filter, out filter);
_columnMappingUIToDb.TryGetValue(sort, out sort);
DataTable contacts = await Task.Run(() => FilterContactsFromMemory(search, filter, sort));
DisplayContacts(contacts);
}
My UI freezes while the contacts are being filtered even tho I wrapped it in await Task.Run(() => ) to make it non-blocking. What can I do so that my UI doesn't freeze while the contacts are being filtered?
10 Replies
WTDawson9
WTDawson915mo ago
Waiting for the task to run wont help You could use Dispatcher.Invoke(() => {}) to do something on the main thread when it's finished Atleast I think its Dispatcher.Invoke(() => {}) Would have to check
Florian Voß
Florian Voß15mo ago
its actually the line after that causes the freeze even If I put a while(true) in the Task.Run() I can interact with UI just fine. its the DisplayContacts that freezes UI I had tried wrapping DisplayContacts() in Dispatcher.Invoke(() =>) already, that's what chat gpt told me to do but I didn't notice a difference
chef drone builder
can you show the code for DisplayContacts
Florian Voß
Florian Voß15mo ago
sure, here:
private void DisplayContacts(DataTable contacts)
{
ContactsView.VerticalAlignment = VerticalAlignment.Top;
if (contacts == null || !contacts.AsEnumerable().Any())
{
ContactScroller.Visibility = Visibility.Hidden;
ContactSearchError.Text = "Es konnten keine übereinstimmenden Kontake gefunden werden";
ContactSearchError.Visibility = Visibility.Visible;
}
else
{
ContactSearchError.Visibility = Visibility.Hidden;
ContactScroller.Visibility = Visibility.Visible;
_filteredContacts = contacts;
ContactsData.ItemsSource = _filteredContacts.DefaultView;
}
}
private void DisplayContacts(DataTable contacts)
{
ContactsView.VerticalAlignment = VerticalAlignment.Top;
if (contacts == null || !contacts.AsEnumerable().Any())
{
ContactScroller.Visibility = Visibility.Hidden;
ContactSearchError.Text = "Es konnten keine übereinstimmenden Kontake gefunden werden";
ContactSearchError.Visibility = Visibility.Visible;
}
else
{
ContactSearchError.Visibility = Visibility.Hidden;
ContactScroller.Visibility = Visibility.Visible;
_filteredContacts = contacts;
ContactsData.ItemsSource = _filteredContacts.DefaultView;
}
}
chef drone builder
so at what point in this method does the program freeze?
Florian Voß
Florian Voß15mo ago
it's hard to figure that out. How do you suggest I do that? if I stop at a breakpoint it won't let me focus windows tab with the UI unless I click "continue" on the debugger in visual studio. Also does it really matter if its the first or last line of this function? every statement in that function is doing roughly similar things, making changes to UI components' properties you probably just worded that badly but just to clarify, not my program is freezing, only the UI is freezing, it cannot be interacted with when DisplayContacts is executing like minimizing the window for example or checking or unchecking a radiobutton etc.
WTDawson9
WTDawson915mo ago
Try console logging at different times Try running it on an external thread then Don't run complex tasks on the main thread
JakenVeina
JakenVeina15mo ago
so, you have so many contracts to throw into the UI that it appears to freeze while it's loading them just the GUI objects for all of them make that method async and toss in some await Task.Yield()s I.E. it's on you to break apart your work so no individual piece is taking up too much time on the UI thread so, instead of pushing ALL the new records up to the UI in one synchronous call maybe push 100 at a time and await Task.Yield() after each batch of 100 that gives the UI thread a chance to do its other stuff, periodically, like requests to paint, and handle mouse and keyboard input, etc. so it stops appearing to hang this may mean you have to manually disable buttons or inputs or anything else the user can mess with, to make sure they don't screw up the load maybe you also want to put up a progress bar
Florian Voß
Florian Voß15mo ago
@ReactiveVeina that sounds promising. I've thought about trying paging too but I didn't know about await Task.Yield() 🤔 gonna try that out tomorrow, excuse the long delay of my responsens, we seem to live in different time zones gonna ping you then and tell you how it went if you dont mind
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.