繁体   English   中英

单独的UI线程上的WPF控件?

[英]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个字符开始搜索。
  • 在用户停止键入之后等待几毫秒并且在开始搜索之前,当用户键入快于几毫秒时,您的搜索词将包含多个字符。 第二个选项包括在用户开始输入时启动计时器,并在按下每个键时将此计时器设置为零(不停止)。 当用户停止键入2000毫秒(例如)时,执行搜索

一种完美的方法是结合这两种技术:只搜索搜索条件中是否有3个或更多字符,并使用计时器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM