I am making a media player, now.. I have added a realtime search function to search for songs etc. (Some thing like WMP realtime search) i.e while you enter the keywords the searching happens.
During the searching process, accessing the database and loading an IEnumerable is done on another thread via a BackGroundProcess. The UI is updated by invoking a dispatcher of a UIElement.
This process is rather fast, but however while you enter the search keywords in the textbox, there seems to be a small lag, this is beacause the Listbox.ItemSource updating takes some time. i.e say you want to search for "Adele", when you type in "a", the search function loads the results for "A", but as we are typing the whole word "Adele" , it some time to display the "d" "e" "l" "e" and there is a slight lag in between these letters.
During this search process, when I stop updating the UI the search process seems very smooth, this only means to me that the Listbox is locking up the thread, so the rest of the player's UI is stuck there while the Listbox is done with its processing.
So I believe if I can put the Listbox Control to another UI thread, I can maintain the smooth flow of the player irrespective of the time taken to load the Listbox. FYI: Data Virutualization is there & ListBox has UI Virtualization is working
How can i put the ListBox control onto another UI Thread? WPF, C#
Thanks in advance :)
If you are querying the database on every keypress - this is going to cause you some lag when typing fast (or even normally)
You would be better off throttling the request, we use this to throttle on the dispatcher thread.
public static class DispatcherExtensions
{
private static Dictionary<string, DispatcherTimer> timers =
new Dictionary<string, DispatcherTimer>();
private static readonly object syncRoot = new object();
public static string DelayInvoke(this Dispatcher dispatcher, string namedInvocation,
Action action, TimeSpan delay,
DispatcherPriority priority = DispatcherPriority.Normal)
{
lock (syncRoot)
{
if (String.IsNullOrEmpty(namedInvocation))
{
namedInvocation = Guid.NewGuid().ToString();
}
else
{
RemoveTimer(namedInvocation);
}
var timer = new DispatcherTimer(delay, priority, (s, e) =>
{
RemoveTimer(namedInvocation);
action();
}, dispatcher);
timer.Start();
timers.Add(namedInvocation, timer);
return namedInvocation;
}
}
public static void CancelNamedInvocation(this Dispatcher dispatcher, string namedInvocation)
{
lock (syncRoot)
{
RemoveTimer(namedInvocation);
}
}
private static void RemoveTimer(string namedInvocation)
{
if (!timers.ContainsKey(namedInvocation)) return;
timers[namedInvocation].Stop();
timers.Remove(namedInvocation);
}
}
Assuming you are not using MVVM, you could easily use this like so in your button click
Dispatcher.CurrentDispatcher.DelayInvoke("UpdateSearch",
YourMethodThatStartsBackgroundThread,Timespan.FromSeconds(1));
Also worth a note : f you are using 4.5 there is the Delay property on bindings you could look at.
In ASP.NET, usualy we use two techiniques
A perfect approach is to combine this two techiniques: Only search if you have 3 or more chars in the search criteria, and use the timer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With