diff --git a/src/VisualStudio/Core/Impl/Options/AbstractOptionPageControl.cs b/src/VisualStudio/Core/Impl/Options/AbstractOptionPageControl.cs index 2d4debbfff06ff16bd8f27a01f15c2df02a44d8a..06f0f577acb8da5167dd8507a1d94a7969a285fe 100644 --- a/src/VisualStudio/Core/Impl/Options/AbstractOptionPageControl.cs +++ b/src/VisualStudio/Core/Impl/Options/AbstractOptionPageControl.cs @@ -32,8 +32,18 @@ public AbstractOptionPageControl(IServiceProvider serviceProvider) var checkBoxStyle = new Style(typeof(CheckBox)); checkBoxStyle.Setters.Add(new Setter(CheckBox.MarginProperty, new Thickness() { Bottom = 7 })); - groupBoxStyle.Setters.Add(new Setter(GroupBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey))); + checkBoxStyle.Setters.Add(new Setter(CheckBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey))); Resources.Add(typeof(CheckBox), checkBoxStyle); + + var textBoxStyle = new Style(typeof(TextBox)); + textBoxStyle.Setters.Add(new Setter(TextBox.MarginProperty, new Thickness() { Left = 7, Right = 7 })); + textBoxStyle.Setters.Add(new Setter(TextBox.ForegroundProperty, new DynamicResourceExtension(SystemColors.WindowTextBrushKey))); + Resources.Add(typeof(TextBox), textBoxStyle); + } + + protected void AddBinding(BindingExpressionBase bindingExpression) + { + _bindingExpressions.Add(bindingExpression); } protected void BindToOption(CheckBox checkbox, Option optionKey) diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryMode.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryMode.cs new file mode 100644 index 0000000000000000000000000000000000000000..dc41d7f87966db6e779aeff3beafac566229af82 --- /dev/null +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryMode.cs @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages +{ + internal class ForceLowMemoryMode + { + private int _size = 500; // default to 500 MB + private MemoryHogger _hogger; + + public static readonly ForceLowMemoryMode Instance = new ForceLowMemoryMode(); + + private ForceLowMemoryMode() + { + } + + public int Size + { + get { return _size; } + set { _size = value; } + } + + public bool Enabled + { + get + { + return _hogger != null; + } + + set + { + if (value && _hogger == null) + { + _hogger = new MemoryHogger(); + var tmp = _hogger.PopulateAndMonitorAsync(this.Size); + } + else if (!value) + { + var hogger = _hogger; + if (hogger != null) + { + _hogger = null; + hogger.Cancel(); + } + } + } + } + + class MemoryHogger + { + private const int BlockSize = 1024 * 1024; // megabyte blocks + private const int MonitorDelay = 10000; // 10 seconds + + private readonly List _blocks = new List(); + private bool _cancelled; + + public MemoryHogger() + { + } + + public int Count + { + get { return _blocks.Count; } + } + + public void Cancel() + { + _cancelled = true; + } + + public Task PopulateAndMonitorAsync(int size) + { + // run on background thread + return Task.Run(() => this.PopulateAndMonitorWorkerAsync(size)); + } + + private async Task PopulateAndMonitorWorkerAsync(int size) + { + try + { + for (int n = 0; n < size && !_cancelled; n++) + { + var block = new byte[BlockSize]; + + // initialize block bits (so they memory actually gets allocated.. silly runtime!) + for (int i = 0; i < BlockSize; i++) + { + block[i] = 0xFF; + } + + _blocks.Add(block); + + // don't hog the thread + await Task.Yield(); + } + } + catch (Exception) + { + } + + // monitor memory to keep it paged in + while (!_cancelled) + { + try + { + // access all block cells + for (var b = 0; b < _blocks.Count && !_cancelled; b++) + { + var block = _blocks[b]; + + for (int i = 0; i < block.Length; i++) + { + var tmp = block[i]; // read bytes from block + } + + // don't hog the thread + await Task.Yield(); + } + } + catch (Exception) + { + } + + await Task.Delay(MonitorDelay); + } + + _blocks.Clear(); + + // force garbage collection + for (int i = 0; i < 5; i++) + { + GC.Collect(GC.MaxGeneration); + GC.WaitForPendingFinalizers(); + } + } + } + } +} diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs index 4e44c7651c80bbf8cbaf5e89f1ecc4ebcb9454a8..5ed986e9cd107edfd53253d99ab48d4071550070 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs @@ -1,10 +1,20 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.LanguageServices.Implementation.Options; +using Roslyn.Utilities; namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages { @@ -13,7 +23,61 @@ internal class InternalFeaturesOnOffPage : AbstractOptionPage { protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider) { - return new InternalOptionsControl(InternalFeatureOnOffOptions.OptionName, serviceProvider); + return new InternalFeaturesOptionsControl(InternalFeatureOnOffOptions.OptionName, serviceProvider); + } + + internal class InternalFeaturesOptionsControl : InternalOptionsControl + { + public InternalFeaturesOptionsControl(string featureOptionName, IServiceProvider serviceProvider) + : base(featureOptionName, serviceProvider) + { + } + + protected override void AddOptions(Panel panel) + { + base.AddOptions(panel); + + // add force low memory mode option + var group = new WrapPanel(); + var lowMemoryMode = ForceLowMemoryMode.Instance; + var cb = CreateBoundCheckBox("Forced Low Memory Mode", lowMemoryMode, "Enabled"); + group.Children.Add(cb); + var tb = CreateBoundTextBox("", lowMemoryMode, "Size"); + group.Children.Add(tb); + var text = new TextBlock() { Text = "MB" }; + group.Children.Add(text); + panel.Children.Add(group); + } + + private CheckBox CreateBoundCheckBox(string content, object source, string sourcePropertyName) + { + var cb = new CheckBox { Content = content }; + + var binding = new Binding() + { + Source = source, + Path = new PropertyPath(sourcePropertyName) + }; + + base.AddBinding(cb.SetBinding(CheckBox.IsCheckedProperty, binding)); + + return cb; + } + + private TextBox CreateBoundTextBox(string content, object source, string sourcePropertyName) + { + var tb = new TextBox { Text = content }; + + var binding = new Binding() + { + Source = source, + Path = new PropertyPath(sourcePropertyName) + }; + + base.AddBinding(tb.SetBinding(TextBox.TextProperty, binding)); + + return tb; + } } } } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs index 702c19691ee5f934c933e159c4e463417e0b952e..66e04b3ef9aaceaf6637311bef3259c924d0f176 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs @@ -12,22 +12,15 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options { internal partial class InternalOptionsControl : AbstractOptionPageControl { + private readonly string _featureOptionName; + public InternalOptionsControl(string featureOptionName, IServiceProvider serviceProvider) : base(serviceProvider) { + _featureOptionName = featureOptionName; + var panel = new StackPanel(); - foreach (var option in OptionService.GetRegisteredOptions().Where(o => o.Feature == featureOptionName).OrderBy(o => o.Name)) - { - if (!option.IsPerLanguage) - { - AddOption(panel, option); - } - else - { - AddPerLanguageOption(panel, option, LanguageNames.CSharp); - AddPerLanguageOption(panel, option, LanguageNames.VisualBasic); - } - } + this.AddOptions(panel); var viewer = new ScrollViewer(); viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; @@ -50,7 +43,23 @@ public InternalOptionsControl(string featureOptionName, IServiceProvider service this.Content = viewer; } - private void AddOption(StackPanel panel, IOption option) + protected virtual void AddOptions(Panel panel) + { + foreach (var option in OptionService.GetRegisteredOptions().Where(o => o.Feature == _featureOptionName).OrderBy(o => o.Name)) + { + if (!option.IsPerLanguage) + { + AddOption(panel, option); + } + else + { + AddPerLanguageOption(panel, option, LanguageNames.CSharp); + AddPerLanguageOption(panel, option, LanguageNames.VisualBasic); + } + } + } + + private void AddOption(Panel panel, IOption option) { var uiElement = CreateControl(option); if (uiElement != null) @@ -59,7 +68,7 @@ private void AddOption(StackPanel panel, IOption option) } } - private void AddPerLanguageOption(StackPanel panel, IOption option, string languageName) + private void AddPerLanguageOption(Panel panel, IOption option, string languageName) { var uiElement = CreateControl(option, languageName); if (uiElement != null) diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindow.csproj b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindow.csproj index d94ddf82ff3d15ced5fcdb05301de60c4ad9dbd8..146fc58e352a72a7699642bf13b6c7727b150d24 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindow.csproj +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindow.csproj @@ -90,7 +90,9 @@ - false + + false + false @@ -113,6 +115,7 @@ +