Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception on load #1

Open
uniquelau opened this issue Apr 2, 2021 · 4 comments · May be fixed by #3
Open

Exception on load #1

uniquelau opened this issue Apr 2, 2021 · 4 comments · May be fixed by #3
Assignees
Labels
bug Something isn't working

Comments

@uniquelau
Copy link

Running .NET 5.0, Blazor PWA
Installed in client project and updated _Import.
Referencing the component directly
SVG is requested by browser.
However, exception is thrown.

image

Throw Exception at TailBlazor.HeroIcons.TailBlazorHeroIconBase.OnInitialized()

      Unhandled exception rendering component: Cannot wait on monitors on this runtime.
System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.
   at System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout, Boolean exitContext)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout)
   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.FinishInitUriString()
   at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver)
   at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
   at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
   at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings)
   at System.Xml.Linq.XDocument.Load(String uri, LoadOptions options)
   at System.Xml.Linq.XDocument.Load(String uri)
   at TailBlazor.HeroIcons.TailBlazorHeroIconBase.OnInitialized()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

SVG requested 3 times (as expected)
image

@TaylorWatson
Copy link
Member

looks related to this.

PlatformNotSupportedException on Blazor Client Side

I will take a look to see if I can work around WASM's limitations.

@TaylorWatson TaylorWatson self-assigned this Apr 7, 2021
@TaylorWatson TaylorWatson added the bug Something isn't working label Apr 7, 2021
@DanteDeRuwe
Copy link

Any updates on this?

@badHax
Copy link

badHax commented Apr 10, 2022

This seems to be related to a thread blocking call in TailBlazorHeroIcon.razor.cs which is definitely not supported in Blazor.

 var document = await Task.Run(() => {
                    return XDocument.Load($"{baseUri}_content/TailBlazor.HeroIcons/icons/{EnumExtension.GetEnumDescription(IconStyle)}/{EnumExtension.GetEnumDescription(Icon)}.svg");
            });

One workaround that I have found is to override this class and load the SVG through an HTTP request and use async method to load it instead:

       //.....
       // Use non blocking HTTP request to stream the SVG
        var client = new HttpClient();
        var icon = (await client.GetAsync(NavigationManager.BaseUri + "_content/TailBlazor.HeroIcons/icons/" +
                                          IconStyle.GetEnumDescription() + "/" + Icon.GetEnumDescription() + ".svg"))
            .Content;
        await using var stream = await icon.ReadAsStreamAsync();

        // load asynchronously
        var root = (await XDocument.LoadAsync(stream, LoadOptions.PreserveWhitespace, CancellationToken.None)).Root;

        root?.SetAttributeValue("width", Width);
        root?.SetAttributeValue("height", Height);
        root?.SetAttributeValue("stroke", "");
        root?.SetAttributeValue("class", _classStroke);
        foreach (var xelement in root?.Descendants().Select((Func<XElement, XElement>)(path => path)) ??
                                 new List<XElement>())
        {
            if (xelement.Attribute("stroke-width") != null)
                xelement.SetAttributeValue("stroke-width", StrokeWidth);
            if (xelement.Attribute("fill") != null)
                xelement.SetAttributeValue("fill", StrokeWidth);
        }

        _svgIcon = root?.ToString();
    //...

Then I created a CustomHeroIcons.cs

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace Custom.Components.HeroIcons
{
    public class CustomHeroIcon : CustomHeroIconBase
    {
        protected override void BuildRenderTree(RenderTreeBuilder __builder)
        {
            if (this.EnableComments)
                __builder.AddContent(0, this._svgIconComment);
            __builder.AddContent(1, (MarkupString)this._svgIcon);
        }
    }
}

Finally, I just use this in my code:

        <button @onclick="NavigateToHome">
          Home
          <CustomHeroIcon Class="tw-h-6 tw-w-6"
                              Icon="HeroIcon.Home"></CustomHeroIcon>
        </button>

@TaylorWatson
Copy link
Member

Thanks, if you want submit a PR or I'll update using this method instead

@badHax badHax linked a pull request Apr 10, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants