[英]WPF Control On Separate UI Thread?
我正在制作一个媒体播放器,现在..我添加了一个实时搜索功能来搜索歌曲等等(有些东西,如WMP实时搜索),即当你输入关键字时,搜索就会发生。
在搜索过程中,访问数据库并加载IEnumerable是通过BackGroundProcess在另一个线程上完成的。 通过调用UIElement的调度程序来更新UI。
这个过程相当快,但是当您在文本框中输入搜索关键字时,似乎存在一个小的延迟,这是因为Listbox.ItemSource更新需要一些时间。 也就是说你要搜索“Adele”,当你输入“a”时,搜索功能会加载“A”的结果,但是当我们输入整个单词“Adele”时,它有时间显示“d” “”e“”“l”“e”并且这些字母之间存在轻微的滞后。
在这个搜索过程中,当我停止更新UI时,搜索过程看起来非常流畅,这只对我意味着Listbox锁定线程,因此当Listbox完成其处理时,播放器的UI的其余部分被卡在那里。
因此,我相信如果我可以将Listbox Control放到另一个UI线程中,无论加载列表框所花费的时间如何,我都可以保持播放器的流畅。 仅供参考:数据虚拟化就在那里,ListBox的UI虚拟化正在运行
如何将ListBox控件放到另一个UI线程上? WPF,C#
提前致谢 :)
如果您在每个按键上查询数据库 - 这会导致您在快速键入(甚至正常)时出现延迟
你最好限制请求,我们用它来调度调度程序线程。
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);
}
}
假设您没有使用MVVM,您可以在单击按钮时轻松使用它
Dispatcher.CurrentDispatcher.DelayInvoke("UpdateSearch",
YourMethodThatStartsBackgroundThread,Timespan.FromSeconds(1));
另外值得注意的是:如果您使用的是4.5,那么您可以查看绑定的Delay属性。
在ASP.NET中,通常我们使用两种技术
一种完美的方法是结合这两种技术:只搜索搜索条件中是否有3个或更多字符,并使用计时器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.