【发布时间】:2013-11-06 02:31:15
【问题描述】:
我刚开始使用 Redis,并且正在将它用于我的个人项目之一。 Redis DB 包含大约 10k 个对象
public Class FileList
{
public string FileName { get; set;}
public string FolderName { get; set;}
}
我最初在加载时在 ListBox ResultsView 中显示此列表。我有一个TextBox,我可以在其中输入字符,在TextBoxChanged_Event 上,我正在调用一个函数,该函数将在RedisDB 中查询包含我在TextBox 中键入的字符的所有FileList 对象并将其存储在一个ResultsList<FileList>,它将在foreach中循环,然后添加到ListBox。
开始显示结果至少需要一秒钟,而且速度不是很快。
现在,如果我对 MasterList<FileList> 执行相同的查询,那么它会快一点,但仍然不够快。
昨天,我尝试使用 RavenDb,它费力地花费了很长时间来完成相同的任务。
是我在forach 中将Items 添加到ListBox 中,这需要花费很多时间,还是有什么可以像ItemSource 那样加快速度的方法,我试过但是给了我ItemList should be empty before binding的错误
我确实尝试了几乎类似问题的大多数答案,但没有一个对我有帮助。
代码
ResultsView.Items.Clear();
var redisClient = new RedisClient("localhost");
using (var client = redisClient.As<FileList>())
{
var foldersFromRedis = client.GetAll().Where(fileList => fileList.FileName.Contains(this.Search.Text.ToLower()));
foreach (FileList fileList in foldersFromRedis)
{
var listViewItem = new ListViewItem { Content = fileList.FileName , Tag = fileList.FolderName };
this.ResultsView.Items.Add(listViewItem);
}
}
//this.ResultsView.ItemsSource = ResultsFileList;
<ListBox Height="374" ScrollViewer.VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Left" Margin="10,0,0,0" Name="ResultsView" VerticalAlignment="Bottom" Width="405" BorderThickness="0" SelectionChanged="MovieNameSelectionChanged" FontFamily="Nobile" FontSize="13" Background="#A6FCFCFC" Foreground="Black" FontStretch="Normal">
<GridView>
<GridViewColumn Header="FileName" DisplayMemberBinding="{Binding FileName}"/>
</GridView>
</ListBox>
更新 1:
添加 ViewCollectionSource 如下
private void ApplyViewCollectionSource()
{
_viewSource.Filter += ViewSourceFilter;
_viewSource.Source = _fileList = (List<FileList>)PopulateFileListEnglishWithReturn();
ResultsView.ItemsSource = _viewSource.View;
_timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
_timer.Tick += (o, e) =>
{
_timer.Stop();
_viewSource.View.Refresh();
};
Search.TextChanged += (o, e) => _timer.Start();
}
在构造函数中被调用。过滤器如下:
private void ViewSourceFilter(object sender, FilterEventArgs e)
{
var src = e.Item as FileList;
e.Accepted = src != null;
if (string.IsNullOrEmpty(Search.Text)) return;
var regex = new Regex(Search.Text, RegexOptions.IgnoreCase);
e.Accepted = regex.IsMatch(src.FileName);
}
这非常适合我的要求,但仅在文本框中的第三个字符之后。输入第一个字符后,ListBox 需要 2 秒才能更新,第二个字符需要 1 秒。在此之后,几乎是瞬间。主列表_fileList大约有5000项。
有什么方法可以提高前 2 个字符搜索的速度?
【问题讨论】:
-
您是如何使用绑定获取
ItemList should be empty before binding的?AlbumName是如何适应这一切的? -
1) 你是否重新加载 TextChanged 中的所有数据?如果是这样考虑缓存几秒。 2) 将
this.Search.Text.ToLower()的值缓存到局部变量中并在Where()中使用 -
@Noctis 是错字,已更正。我只是设置了 ItemSource={Binding} 并在代码隐藏中设置了 ItemSource。
-
从
ListBox中移除GridView。这是完全错误的。
标签: c# wpf listbox redis .net-4.5