减少内存占用

发布于 2025-01-08 14:16:44 字数 393 浏览 0 评论 0原文

我有一个包含超过 100,000 个项目的主流 (IEnumerable)。然后我的控件中有多个 AutoCompleteBox 。所有这些 AutoCompleteBox 都绑定到主流。

首先:

现在的问题是我的控件中有大约 10 个 AutoCompleteBox,并且全部都将 Main Stream 作为其 ItemsSource,从而导致内存占用较大。

第二:

我还需要有一个功能,可以根据某些事件在运行时对几个 AutoCompleteBox 的 ItemsSource 应用过滤器。

我需要您的建议来减少内存占用,并具有在运行时应用过滤器的功能。

I have a Main Stream (IEnumerable) with more than 100,000 items. And then I have multiple AutoCompleteBox in my control. All those AutoCompleteBox are bound to the Main Stream.

First:

Now the problem is I have around 10 AutoCompleteBox in my control and all having Main Stream as their ItemsSource thus resulting in large memory footprint.

Second:

I also need to have a functionality to apply filters on few AutoCompleteBox's ItemsSource at runtime depending upon some events.

I need yours suggestions to reduce this memory footprint and have a functionality to apply filters on runtime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风向决定发型 2025-01-15 14:16:44

对于数据收集的内存占用,您应该查找 Sequential Data Cache

示例以减少内存消耗:

    public void TestAutoCompleteLookup()
    {
        var path = "";
        using (var c = SequentialDataCache<AutoCompleteItem>.Initialize())
        {
            path = c.Path;

            //add 100.000 items 
            for (int i = 0; i < 100000; i++)
            {
                c.Add(new AutoCompleteItem() { Text = string.Format("{0}Text", i) });
            }

            //query
            var pattern = "1";
            var items = c.Where(autoCompleteItem => autoCompleteItem.Text.StartsWith(pattern)).ToArray();

        }

        if (File.Exists(path))
            File.Delete(path);
    }

    [Serializable]
    private class AutoCompleteItem
    {
        public string Text { get; set; }
    }

For the memory footprint of the data collection you should look for Sequential Data Cache

Sample to reduce the memory consumption:

    public void TestAutoCompleteLookup()
    {
        var path = "";
        using (var c = SequentialDataCache<AutoCompleteItem>.Initialize())
        {
            path = c.Path;

            //add 100.000 items 
            for (int i = 0; i < 100000; i++)
            {
                c.Add(new AutoCompleteItem() { Text = string.Format("{0}Text", i) });
            }

            //query
            var pattern = "1";
            var items = c.Where(autoCompleteItem => autoCompleteItem.Text.StartsWith(pattern)).ToArray();

        }

        if (File.Exists(path))
            File.Delete(path);
    }

    [Serializable]
    private class AutoCompleteItem
    {
        public string Text { get; set; }
    }
稚然 2025-01-15 14:16:44

内存占用

我相信这不仅取决于您的代码实现,还取决于 AutocompleteControl 以及它如何使用绑定数据源。

  • 在 getter 中将 MainStream 实现为具有 yield return 的计算属性,以便在运行时按需计算/返回项目

  • 对于 WPF4,请查看是否使用 WPF 数据虚拟化的 AutocompleteControl。基本上,您可以重新定义标准项目面板以使用 VirtualizingStackPanel 而不是 StackPanel,这样框架将为可见项目分配内存并创建 UI 元素,而不是为所有绑定的项目。

动态过滤

看一下 MVVM 方法。可以很容易地使用绑定到 UI 过滤器控件的属性来计算 MainSTream 项目,基本上 getter 将使用公共绑定属性,并且每次更改这些属性时 - MainSTream 都会重新计算项目并通过 INotifyPropertyChanged 通知 UI,显然您需要实现对 INotifyPropertyChanged 的​​支持。请参阅一句话解释WPF中的MVVM?

public IEnumerable<IMyItem> MainStream
{
   get
   {
      foreach(var item in mainDataSource)
      {
         if (item.Name == this.NameFilterBoundToUiTextBox)
         { 
            yield return item;
         }
      }
   }
}

private string nameFilter;
public string NameFilterBoundToUiTextBox
{
   get
   {
       return this.nameFilter;
   }
   set
   {  
      if (this.nameFilter != value)
      {
         this.nameFilter = value;

         // TODO: Implement INotifyPropertyChanged
         this.OnPropertyChanged("NameFilterBoundToUiTextBox");

         // THis would notify UI to rebind MainSream
         this.OnPropertyChanged("MainStream");
      }
   }
}

Memory footprint

I believe it depends not only from your code implementation but from AutocompleteControlas well, how it uses the bound data source.

  • Implement MainStream as calculated property with yield return in the getter so items would be calculated/returned on-demand in runtime

  • For WPF4 see whether AutocompleteControl using WPF Data Virtualization. Basically you can redefine standard items panel to use VirtualizingStackPanel instead of StackPanel so framework would allocate memory and create UI elements only for visible items, not for the all bound.

On-the-fly filtering

Take a look at the MVVM approach. It would be easily use properties bound to UI filter control to calculate MainSTream items, basically getter would use public bound properties and each time any of those has been changed - MainSTream would recalculate items and notify UI via INotifyPropertyChanged, obviously you need to implement support of the INotifyPropertyChanged. See One sentence explanation to MVVM in WPF?

public IEnumerable<IMyItem> MainStream
{
   get
   {
      foreach(var item in mainDataSource)
      {
         if (item.Name == this.NameFilterBoundToUiTextBox)
         { 
            yield return item;
         }
      }
   }
}

private string nameFilter;
public string NameFilterBoundToUiTextBox
{
   get
   {
       return this.nameFilter;
   }
   set
   {  
      if (this.nameFilter != value)
      {
         this.nameFilter = value;

         // TODO: Implement INotifyPropertyChanged
         this.OnPropertyChanged("NameFilterBoundToUiTextBox");

         // THis would notify UI to rebind MainSream
         this.OnPropertyChanged("MainStream");
      }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文