简体   繁体   English

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

[英]WPF Control On Separate UI Thread?

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) ie while you enter the keywords the searching happens. 我正在制作一个媒体播放器,现在..我添加了一个实时搜索功能来搜索歌曲等等(有些东西,如WMP实时搜索),即当你输入关键字时,搜索就会发生。

During the searching process, accessing the database and loading an IEnumerable is done on another thread via a BackGroundProcess. 在搜索过程中,访问数据库并加载IEnumerable是通过BackGroundProcess在另一个线程上完成的。 The UI is updated by invoking a dispatcher of a UIElement. 通过调用UIElement的调度程序来更新UI。

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. 这个过程相当快,但是当您在文本框中输入搜索关键字时,似乎存在一个小的延迟,这是因为Listbox.ItemSource更新需要一些时间。 ie 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. 也就是说你要搜索“Adele”,当你输入“a”时,搜索功能会加载“A”的结果,但是当我们输入整个单词“Adele”时,它有时间显示“d” “”e“”“l”“e”并且这些字母之间存在轻微的滞后。

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. 在这个搜索过程中,当我停止更新UI时,搜索过程看起来非常流畅,这只对我意味着Listbox锁定线程,因此当Listbox完成其处理时,播放器的UI的其余部分被卡在那里。

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. 因此,我相信如果我可以将Listbox Control放到另一个UI线程中,无论加载列表框所花费的时间如何,我都可以保持播放器的流畅。 FYI: Data Virutualization is there & ListBox has UI Virtualization is working 仅供参考:数据虚拟化就在那里,ListBox的UI虚拟化正在运行

How can i put the ListBox control onto another UI Thread? 如何将ListBox控件放到另一个UI线程上? WPF, C# 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 假设您没有使用MVVM,您可以在单击按钮时轻松使用它

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. 另外值得注意的是:如果您使用的是4.5,那么您可以查看绑定的Delay属性。

In ASP.NET, usualy we use two techiniques 在ASP.NET中,通常我们使用两种技术

  • Wait for at most 3 char to begin the search. 等待最多3个字符开始搜索。
  • Waiting some milliseconds after de user stop typing and before start the search, as the user types fast than some miliseconds, your search term will contains more than one char. 在用户停止键入之后等待几毫秒并且在开始搜索之前,当用户键入快于几毫秒时,您的搜索词将包含多个字符。 This second option consists in start a timer when the user start to type and set this timer to zero (without stop it) every key pressed. 第二个选项包括在用户开始输入时启动计时器,并在按下每个键时将此计时器设置为零(不停止)。 When the user stops to typing for 2000 milliseconds (by example) you perform the search 当用户停止键入2000毫秒(例如)时,执行搜索

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

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

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