Comments (5)
Rion, this is Todd from the VS webtools team (I'm not on twitter). Is the exception due to something the VS webtooling code is providing? I took a quick look at the code and it looked like it wasn't.
from glyphfriend.
Hi @ToddGrun,
Thanks for reaching out. So it looks like the issue is stemming from how some of the Glyphs are being served to the CompletionHandler, which is probably a pattern that needs to be addressed (but I'm not entirely sure the best way to do it in the 2019 world).
The flow of the application goes as follows:
- Prior to the extension being built, all of the supported glyphs (~6-7k of them) are serialized into a .bin file with all of the libraries they correspond to, image data, and the text that appears during autocompletion.
- When the extension starts up, this .bin file is read and deserialized into a collection that the extension uses to determine which glyphs to serve.
I think a big part of this problem is that process in earlier version of the extension used to be synchronous:
public sealed class VSPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
await Logger.InitializeAsync(this, "Glyphfriend");
// This is where the glyphs are being loaded and referenced from
await GlyphfriendPreferences.InitializeAsync();
await ToggleLibraryCommand.InitializeAsync(this);
}
}
The GlyphfriendPreferences
class is initialized, during which the .bin file is deserialized into the collection:
public static class GlyphfriendPreferences
{
// The primary glyphs collection that gets loaded from the .bin file
public static List<Glyph> Glyphs { get; private set; }
public static async System.Threading.Tasks.Task InitializeAsync()
{
// Omitted for brevity
Glyphs = LoadSupportedGlyphs();
// Omitted for brevity
}
private static List<Glyph> LoadSupportedGlyphs()
{
var binaryPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "glyphs.bin");
using (var fs = File.Open(binaryPath, FileMode.Open))
{
var glyphs = Serializer.Deserialize<List<Glyph>>(fs);
glyphs.ForEach(g => g.GenerateImage());
Logger.Log($"{glyphs.Count} glyphs found.");
return glyphs;
}
}
}
And finally the Completion Provider will read these (directly from this class, which may be an issue) as the user starts typing:
[HtmlCompletionProvider(CompletionTypes.Values, "*", "class")]
[ContentType("htmlx")]
internal class GlyphCompletionListProvider : BaseHtmlCompletionListProvider
{
public override string CompletionType { get { return CompletionTypes.Values; } }
public override IList<HtmlCompletion> GetEntries(HtmlCompletionContext context)
{
var glyphCompletionItems = new List<HtmlCompletion>();
// Get the filtered set of enabled glyphs (directly from the preferences class)
var enabledGlyphs = Preferences.Glyphs.Where(g => g.Enabled);
foreach (var glyph in enabledGlyphs)
{
glyphCompletionItems.Add(CreateItem(glyph.Name, glyph.Image, context.Session));
}
return glyphCompletionItems;
}
}
It may be possible that this is a threading (UI vs Main) issue or the fact that there's a race-condition type issue where the autocompletion is engaging prior to the .bin file being properly serialized.
Is there a better way to do this? I'm almost certain that it's an issue with the serialization/loading not being done prior to being accessed.
from glyphfriend.
Depends on the experience desired, I guess.
If you are content to not show the glyphs if deserialization isn't yet completed, then a simple null check on Preferences.Glyphs is probably sufficient as it's populated via an assignment from a local.
If you wish to have your provider block until deserialization is completed, then JTF.Run is probably appropriate (and you'll probably want to make GlyphfriendPreferences.Glyphs return a Task<List>)
from glyphfriend.
Thanks Todd,
I'll give those a shot. Everything seemed to work as expected on a few versions back but once I updated Visual Studio to the latest version, this started to come up. I do suspect that this is part/all of the issue (as some stack traces that I had seen in the past mentioned access to the glyph from another thread).
from glyphfriend.
It looks like this recent fix addressed the issue that a few users had reported. I was able to reproduce it and confirm that the latest release fixes the problem.
Thanks @ToddGrun for your suggestions and help, I really appreciate it!
from glyphfriend.
Related Issues (20)
- Update Octicons Library (to 5.0.1)
- After Install VS Still Says Missing HOT 2
- Non-functional Autocompletion Behavior HOT 1
- Visual Studio MPF 15.0 Dependency HOT 3
- Failed to initialize settings for Isolated Shell C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\ssms.exe: Unable to find an entry point named '?' in DLL 'PkgdefMgmt.dll'. HOT 2
- Visual Studio 2017 HOT 3
- VS2015 Web Essentials 2015.3 Duplicate Context Menu Items in Code Editor HOT 1
- Add IcoMoon Support
- Add support for RPG Awesome fonts HOT 1
- Material Angular support
- Not working in Visual Studio 2017 HOT 3
- Add support for font awesome 5
- Visual Studio Code support? HOT 1
- wpf support HOT 1
- Support for Visual Studio 2019 HOT 9
- Glyphfriend does not work with .aspx, .ascx, .master, cshtml pages HOT 5
- Support for Open Iconic
- [Feature Request] Enable support for VS 2019 "Experimental Razor editor"
- Visual Studio 2022 Support HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from glyphfriend.