From 9a04a2cb68847ad23fee8748c172cc66a763a5e4 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 3 Feb 2023 17:08:45 +0100 Subject: [PATCH 1/6] wip --- src/Components/Web.JS/src/GlobalExports.ts | 4 +- .../Web.JS/src/Platform/Mono/MonoPlatform.ts | 124 +++++++----------- .../src/Services/LazyAssemblyLoader.cs | 86 ++++++------ 3 files changed, 94 insertions(+), 120 deletions(-) diff --git a/src/Components/Web.JS/src/GlobalExports.ts b/src/Components/Web.JS/src/GlobalExports.ts index 4fca849b69ff..d36952a58d35 100644 --- a/src/Components/Web.JS/src/GlobalExports.ts +++ b/src/Components/Web.JS/src/GlobalExports.ts @@ -53,11 +53,9 @@ interface IBlazor { renderBatch?: (browserRendererId: number, batchAddress: Pointer) => void, getConfig?: (dotNetFileName: System_String) => System_Object | undefined, getApplicationEnvironment?: () => System_String, - readLazyAssemblies?: () => System_Array, - readLazyPdbs?: () => System_Array, readSatelliteAssemblies?: () => System_Array, - getLazyAssemblies?: any dotNetCriticalError?: any + loadLazyAssembly?: any, getSatelliteAssemblies?: any, sendJSDataStream?: (data: any, streamId: number, chunkSize: number) => void, getJSDataStreamChunk?: (data: any, position: number, chunkSize: number) => Promise, diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index be4fecb69f7b..94f5b8a78dde 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -12,7 +12,7 @@ import { Platform, System_Array, Pointer, System_Object, System_String, HeapLock import { WebAssemblyBootResourceType } from '../WebAssemblyStartOptions'; import { BootJsonData, ICUDataMode } from '../BootConfig'; import { Blazor } from '../../GlobalExports'; -import { RuntimeAPI, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, AssetEntry, ResourceRequest } from 'dotnet'; +import { RuntimeAPI, CreateDotnetRuntimeType, DotnetModuleConfig, EmscriptenModule, AssetEntry } from 'dotnet'; import { BINDINGType, MONOType } from 'dotnet/dotnet-legacy'; // initially undefined and only fully initialized after createEmscriptenModuleInstance() @@ -144,13 +144,13 @@ export const monoPlatform: Platform = { return ((baseAddress as any as number) + (fieldOffset || 0)) as any as T; }, - beginHeapLock: function() { + beginHeapLock: function () { assertHeapIsNotLocked(); currentHeapLock = new MonoHeapLock(); return currentHeapLock; }, - invokeWhenHeapUnlocked: function(callback) { + invokeWhenHeapUnlocked: function (callback) { // This is somewhat like a sync context. If we're not locked, just pass through the call directly. if (!currentHeapLock) { callback(); @@ -225,7 +225,7 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc // If anything writes to stderr, treat it as a critical exception. The underlying runtime writes // to stderr if a truly critical problem occurs outside .NET code. Note that .NET unhandled // exceptions also reach this, but via a different code path - see dotNetCriticalError below. - console.error(line); + console.error(line || '(null)'); showErrorNotification(); }; const existingPreRun = moduleConfig.preRun || [] as any; @@ -233,12 +233,12 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc (moduleConfig as any).preloadPlugins = []; let resourcesLoaded = 0; - function setProgress(){ - resourcesLoaded++; - const percentage = resourcesLoaded / totalResources.length * 100; - document.documentElement.style.setProperty('--blazor-load-percentage', `${percentage}%`); - document.documentElement.style.setProperty('--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`); - } + function setProgress() { + resourcesLoaded++; + const percentage = resourcesLoaded / totalResources.length * 100; + document.documentElement.style.setProperty('--blazor-load-percentage', `${percentage}%`); + document.documentElement.style.setProperty('--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`); + } const monoToBlazorAssetTypeMap: { [key: string]: WebAssemblyBootResourceType | undefined } = { 'assembly': 'assembly', @@ -280,7 +280,9 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc // Begin loading the .dll/.pdb/.wasm files, but don't block here. Let other loading processes run in parallel. const assembliesBeingLoaded = resourceLoader.loadResources(resources.assembly, filename => `_framework/${filename}`, 'assembly'); - const pdbsBeingLoaded = resourceLoader.loadResources(resources.pdb || {}, filename => `_framework/${filename}`, 'pdb'); + const pdbsBeingLoaded = hasDebuggingEnabled() + ? resourceLoader.loadResources(resources.pdb || {}, filename => `_framework/${filename}`, 'pdb') + : []; const totalResources = assembliesBeingLoaded.concat(pdbsBeingLoaded, runtimeAssetsBeingLoaded); const dotnetTimeZoneResourceName = 'dotnet.timezones.blat'; @@ -340,7 +342,8 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc assembliesBeingLoaded.forEach(r => addResourceAsAssembly(r, changeExtension(r.name, '.dll'))); pdbsBeingLoaded.forEach(r => addResourceAsAssembly(r, r.name)); - Blazor._internal.dotNetCriticalError = (message) => printErr(message || '(null)'); + Blazor._internal.dotNetCriticalError = printErr; + Blazor._internal.loadLazyAssembly = loadLazyAssembly; // Wire-up callbacks for satellite assemblies. Blazor will call these as part of the application // startup sequence to load satellite assemblies for the application's culture. @@ -372,76 +375,37 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc return BINDING.js_to_mono_obj(Promise.resolve(0)); }; - const lazyResources: { - assemblies?: (ArrayBuffer | null)[], - pdbs?: (ArrayBuffer | null)[] - } = {}; - Blazor._internal.getLazyAssemblies = (assembliesToLoadDotNetArray) => { - const assembliesToLoad = BINDING.mono_array_to_js_array(assembliesToLoadDotNetArray); - const lazyAssemblies = resourceLoader.bootConfig.resources.lazyAssembly; - - if (!lazyAssemblies) { - throw new Error("No assemblies have been marked as lazy-loadable. Use the 'BlazorWebAssemblyLazyLoad' item group in your project file to enable lazy loading an assembly."); - } - - const assembliesMarkedAsLazy = assembliesToLoad!.filter(assembly => lazyAssemblies.hasOwnProperty(assembly)); - - if (assembliesMarkedAsLazy.length !== assembliesToLoad!.length) { - const notMarked = assembliesToLoad!.filter(assembly => !assembliesMarkedAsLazy.includes(assembly)); - throw new Error(`${notMarked.join()} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`); - } + }; - let pdbPromises: Promise<(ArrayBuffer | null)[]> | undefined; - if (hasDebuggingEnabled()) { - const pdbs = resourceLoader.bootConfig.resources.pdb; - const pdbsToLoad = assembliesMarkedAsLazy.map(a => changeExtension(a, '.pdb')); - if (pdbs) { - pdbPromises = Promise.all(pdbsToLoad - .map(pdb => lazyAssemblies.hasOwnProperty(pdb) ? resourceLoader.loadResource(pdb, `_framework/${pdb}`, lazyAssemblies[pdb], 'pdb') : null) - .map(async resource => resource ? (await resource.response).arrayBuffer() : null)); - } - } + async function loadLazyAssembly(assemblyNameToLoad: string, allocator: (dllLength: number, pdbLength: number) => number, loader: (dllLength: number, pdbLength: number) => void): Promise { + const lazyAssemblies = resources.lazyAssembly; + if (!lazyAssemblies) { + throw new Error("No assemblies have been marked as lazy-loadable. Use the 'BlazorWebAssemblyLazyLoad' item group in your project file to enable lazy loading an assembly."); + } - const resourcePromises = Promise.all(assembliesMarkedAsLazy - .map(assembly => resourceLoader.loadResource(assembly, `_framework/${assembly}`, lazyAssemblies[assembly], 'assembly')) - .map(async resource => (await resource.response).arrayBuffer())); - - - return BINDING.js_to_mono_obj(Promise.all([resourcePromises, pdbPromises]).then(values => { - lazyResources['assemblies'] = values[0]; - lazyResources['pdbs'] = values[1]; - if (lazyResources['assemblies'].length) { - Blazor._internal.readLazyAssemblies = () => { - const { assemblies } = lazyResources; - if (!assemblies) { - return BINDING.mono_obj_array_new(0); - } - const assemblyBytes = BINDING.mono_obj_array_new(assemblies.length); - for (let i = 0; i < assemblies.length; i++) { - const assembly = assemblies[i] as ArrayBuffer; - BINDING.mono_obj_array_set(assemblyBytes, i, BINDING.js_typed_array_to_array(new Uint8Array(assembly))); - } - return assemblyBytes as any; - }; - - Blazor._internal.readLazyPdbs = () => { - const { assemblies, pdbs } = lazyResources; - if (!assemblies) { - return BINDING.mono_obj_array_new(0); - } - const pdbBytes = BINDING.mono_obj_array_new(assemblies.length); - for (let i = 0; i < assemblies.length; i++) { - const pdb = pdbs && pdbs[i] ? new Uint8Array(pdbs[i] as ArrayBufferLike) : new Uint8Array(); - BINDING.mono_obj_array_set(pdbBytes, i, BINDING.js_typed_array_to_array(pdb)); - } - return pdbBytes as any; - }; - } - - return lazyResources['assemblies'].length; - })); - }; - }; + const assemblyMarkedAsLazy = lazyAssemblies.hasOwnProperty(assemblyNameToLoad); + if (!assemblyMarkedAsLazy) { + throw new Error(`${assemblyNameToLoad} must be marked with 'BlazorWebAssemblyLazyLoad' item group in your project file to allow lazy-loading.`); + } + const dllNameToLoad = changeExtension(assemblyNameToLoad, '.dll'); + const pdbNameToLoad = changeExtension(assemblyNameToLoad, '.pdb'); + const shouldLoadPdb = hasDebuggingEnabled() && resources.pdb && lazyAssemblies.hasOwnProperty(pdbNameToLoad); + + const dllBytesPromise = resourceLoader.loadResource(dllNameToLoad, `_framework/${dllNameToLoad}`, lazyAssemblies[dllNameToLoad], 'assembly').response.then(response => response.arrayBuffer()); + if (shouldLoadPdb) { + const pdbBytesPromise = await resourceLoader.loadResource(pdbNameToLoad, `_framework/${pdbNameToLoad}`, lazyAssemblies[pdbNameToLoad], 'pdb').response.then(response => response.arrayBuffer()); + const [dllBytes, pdbBytes] = await Promise.all([dllBytesPromise, pdbBytesPromise]); + const pinnedBuffer = allocator(dllBytes.byteLength, pdbBytes.byteLength); + Module.HEAPU8.set(new Uint8Array(dllBytes), pinnedBuffer); + Module.HEAPU8.set(new Uint8Array(pdbBytes), pinnedBuffer + dllBytes.byteLength); + loader(dllBytes.byteLength, pdbBytes.byteLength); + } else { + const dllBytes = await dllBytesPromise; + const pinnedBuffer = allocator(dllBytes.byteLength, 0); + Module.HEAPU8.set(new Uint8Array(dllBytes), pinnedBuffer); + loader(dllBytes.byteLength, 0); + } + } const postRun = () => { if (resourceLoader.bootConfig.debugBuild && resourceLoader.bootConfig.cacheBootResources) { diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index e739793b9edf..42cec18cffd2 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -3,8 +3,11 @@ using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Runtime.InteropServices.JavaScript; using System.Runtime.Loader; using Microsoft.JSInterop; +using System.Linq; +using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Components.WebAssembly.Services; @@ -13,13 +16,8 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Services; /// /// Supports finding pre-loaded assemblies in a server or pre-rendering context. /// -public sealed class LazyAssemblyLoader +public sealed partial class LazyAssemblyLoader { - internal const string GetLazyAssemblies = "window.Blazor._internal.getLazyAssemblies"; - internal const string ReadLazyAssemblies = "window.Blazor._internal.readLazyAssemblies"; - internal const string ReadLazyPDBs = "window.Blazor._internal.readLazyPdbs"; - - private readonly IJSRuntime _jsRuntime; private HashSet? _loadedAssemblyCache; /// @@ -28,7 +26,6 @@ public sealed class LazyAssemblyLoader /// The . public LazyAssemblyLoader(IJSRuntime jsRuntime) { - _jsRuntime = jsRuntime; } /// @@ -104,39 +101,54 @@ private async Task> LoadAssembliesInClientAsync(IEnumerabl return Array.Empty(); } - var jsRuntime = (IJSUnmarshalledRuntime)_jsRuntime; -#pragma warning disable CS0618 // Type or member is obsolete - var count = (int)await jsRuntime.InvokeUnmarshalled>( - GetLazyAssemblies, - newAssembliesToLoad.ToArray()); -#pragma warning restore CS0618 // Type or member is obsolete - - if (count == 0) - { - return Array.Empty(); - } - var loadedAssemblies = new List(); -#pragma warning disable CS0618 // Type or member is obsolete - var assemblies = jsRuntime.InvokeUnmarshalled(ReadLazyAssemblies); - var pdbs = jsRuntime.InvokeUnmarshalled(ReadLazyPDBs); -#pragma warning restore CS0618 // Type or member is obsolete - - for (int i = 0; i < assemblies.Length; i++) + var pendingLoads = newAssembliesToLoad.Select(async assemblyToLoad => { - // The runtime loads assemblies into an isolated context by default. As a result, - // assemblies that are loaded via Assembly.Load aren't available in the app's context - // AKA the default context. To work around this, we explicitly load the assemblies - // into the default app context. - var assembly = assemblies[i]; - var pdb = pdbs[i]; - var loadedAssembly = pdb.Length == 0 ? - AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(assembly)) : - AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(assembly), new MemoryStream(pdb)); - loadedAssemblies.Add(loadedAssembly); - _loadedAssemblyCache.Add(loadedAssembly.GetName().Name + ".dll"); - } + byte[]? buffer = null; + GCHandle pinnedArray = default; + Func allocator = (dllLength, pdbLength) => + { + buffer = new byte[dllLength + pdbLength]; + pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned); + return pinnedArray.AddrOfPinnedObject(); + }; + Action loader = (dllLength, pdbLength) => + { + if (buffer == null) + { + throw new InvalidOperationException("The buffer should not be null."); + } + + Assembly loadedAssembly; + if (pdbLength == 0) + { + loadedAssembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(buffer)); + } + else + { + loadedAssembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(buffer, 0, dllLength), new MemoryStream(buffer, dllLength, pdbLength)); + } + loadedAssemblies.Add(loadedAssembly); + _loadedAssemblyCache.Add(assemblyToLoad); + }; + + await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad, allocator, loader); + if (pinnedArray.IsAllocated) + { + pinnedArray.Free(); + } + }); + + await Task.WhenAll(pendingLoads); return loadedAssemblies; } + + private partial class LazyAssemblyLoaderInterop + { + [JSImport("Blazor._internal.loadLazyAssembly", "blazor-internal")] + public static partial Task LoadLazyAssembly(string assemblyToLoad, + [JSMarshalAs>] Func allocator, + [JSMarshalAs>] Action loader); + } } From 0772f329a9efc9001466171fa5b4ac6b780fa2db Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 6 Feb 2023 10:55:49 +0100 Subject: [PATCH 2/6] simplified --- .../Web.JS/src/Platform/Mono/MonoPlatform.ts | 17 ++--- .../src/Services/LazyAssemblyLoader.cs | 63 +++++++------------ 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 94f5b8a78dde..3a4f03c802ab 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -377,7 +377,7 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc }; - async function loadLazyAssembly(assemblyNameToLoad: string, allocator: (dllLength: number, pdbLength: number) => number, loader: (dllLength: number, pdbLength: number) => void): Promise { + async function loadLazyAssembly(assemblyNameToLoad: string): Promise<{ dll: Uint8Array, pdb: Uint8Array | null }> { const lazyAssemblies = resources.lazyAssembly; if (!lazyAssemblies) { throw new Error("No assemblies have been marked as lazy-loadable. Use the 'BlazorWebAssemblyLazyLoad' item group in your project file to enable lazy loading an assembly."); @@ -395,15 +395,16 @@ async function createEmscriptenModuleInstance(resourceLoader: WebAssemblyResourc if (shouldLoadPdb) { const pdbBytesPromise = await resourceLoader.loadResource(pdbNameToLoad, `_framework/${pdbNameToLoad}`, lazyAssemblies[pdbNameToLoad], 'pdb').response.then(response => response.arrayBuffer()); const [dllBytes, pdbBytes] = await Promise.all([dllBytesPromise, pdbBytesPromise]); - const pinnedBuffer = allocator(dllBytes.byteLength, pdbBytes.byteLength); - Module.HEAPU8.set(new Uint8Array(dllBytes), pinnedBuffer); - Module.HEAPU8.set(new Uint8Array(pdbBytes), pinnedBuffer + dllBytes.byteLength); - loader(dllBytes.byteLength, pdbBytes.byteLength); + return { + dll: new Uint8Array(dllBytes), + pdb: new Uint8Array(pdbBytes), + }; } else { const dllBytes = await dllBytesPromise; - const pinnedBuffer = allocator(dllBytes.byteLength, 0); - Module.HEAPU8.set(new Uint8Array(dllBytes), pinnedBuffer); - loader(dllBytes.byteLength, 0); + return { + dll: new Uint8Array(dllBytes), + pdb: null, + }; } } diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index 42cec18cffd2..f87491067d8e 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -7,7 +7,7 @@ using System.Runtime.Loader; using Microsoft.JSInterop; using System.Linq; -using System.Runtime.InteropServices; +using System.Runtime.Versioning; namespace Microsoft.AspNetCore.Components.WebAssembly.Services; @@ -67,6 +67,7 @@ private static Task> LoadAssembliesInServerAsync(IEnumerab } [RequiresUnreferencedCode("Types and members the loaded assemblies depend on might be removed")] + [SupportedOSPlatform("browser")] private async Task> LoadAssembliesInClientAsync(IEnumerable assembliesToLoad) { if (_loadedAssemblyCache is null) @@ -102,53 +103,33 @@ private async Task> LoadAssembliesInClientAsync(IEnumerabl } var loadedAssemblies = new List(); - var pendingLoads = newAssembliesToLoad.Select(async assemblyToLoad => - { - byte[]? buffer = null; - GCHandle pinnedArray = default; - - Func allocator = (dllLength, pdbLength) => - { - buffer = new byte[dllLength + pdbLength]; - pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned); - return pinnedArray.AddrOfPinnedObject(); - }; - Action loader = (dllLength, pdbLength) => - { - if (buffer == null) - { - throw new InvalidOperationException("The buffer should not be null."); - } - - Assembly loadedAssembly; - if (pdbLength == 0) - { - loadedAssembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(buffer)); - } - else - { - loadedAssembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(buffer, 0, dllLength), new MemoryStream(buffer, dllLength, pdbLength)); - } - loadedAssemblies.Add(loadedAssembly); - _loadedAssemblyCache.Add(assemblyToLoad); - }; - - await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad, allocator, loader); - if (pinnedArray.IsAllocated) - { - pinnedArray.Free(); - } - }); + var pendingLoads = newAssembliesToLoad.Select(assemblyToLoad => LoadAssembly(assemblyToLoad, loadedAssemblies)); await Task.WhenAll(pendingLoads); return loadedAssemblies; } + [RequiresUnreferencedCode("Types and members the loaded assemblies depend on might be removed")] + [SupportedOSPlatform("browser")] + private async Task LoadAssembly(string assemblyToLoad, List loadedAssemblies) + { + JSObject files = await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad); + + byte[] dllBytes = files.GetPropertyAsByteArray("dll")!; + byte[]? pdbBytes = files.GetPropertyAsByteArray("pdb"); + Assembly loadedAssembly = pdbBytes == null + ? AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes)) + : AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes), new MemoryStream(pdbBytes)); + + loadedAssemblies.Add(loadedAssembly); + _loadedAssemblyCache!.Add(assemblyToLoad); + + files.Dispose(); + } + private partial class LazyAssemblyLoaderInterop { [JSImport("Blazor._internal.loadLazyAssembly", "blazor-internal")] - public static partial Task LoadLazyAssembly(string assemblyToLoad, - [JSMarshalAs>] Func allocator, - [JSMarshalAs>] Action loader); + public static partial Task LoadLazyAssembly(string assemblyToLoad); } } From 78067434309c137b68ef6e975281c28e5fa544eb Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Tue, 7 Feb 2023 09:09:43 +0100 Subject: [PATCH 3/6] Update src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs Co-authored-by: Mackinnon Buck --- .../WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index f87491067d8e..1dc60ad01b28 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -113,7 +113,7 @@ private async Task> LoadAssembliesInClientAsync(IEnumerabl [SupportedOSPlatform("browser")] private async Task LoadAssembly(string assemblyToLoad, List loadedAssemblies) { - JSObject files = await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad); + using var files = await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad); byte[] dllBytes = files.GetPropertyAsByteArray("dll")!; byte[]? pdbBytes = files.GetPropertyAsByteArray("pdb"); From d1bccf280a2df1fc507b9495ff3bd8969942a09d Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Tue, 7 Feb 2023 09:09:50 +0100 Subject: [PATCH 4/6] Update src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs Co-authored-by: Mackinnon Buck --- .../WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index 1dc60ad01b28..bc94c8b96f93 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -124,7 +124,6 @@ private async Task LoadAssembly(string assemblyToLoad, List loadedAsse loadedAssemblies.Add(loadedAssembly); _loadedAssemblyCache!.Add(assemblyToLoad); - files.Dispose(); } private partial class LazyAssemblyLoaderInterop From 983bd95f44d911f1f058db5042ef4323ae685d66 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 7 Feb 2023 09:41:45 +0100 Subject: [PATCH 5/6] feedback --- src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 3a4f03c802ab..14161f5b34a2 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -144,13 +144,13 @@ export const monoPlatform: Platform = { return ((baseAddress as any as number) + (fieldOffset || 0)) as any as T; }, - beginHeapLock: function () { + beginHeapLock: function() { assertHeapIsNotLocked(); currentHeapLock = new MonoHeapLock(); return currentHeapLock; }, - invokeWhenHeapUnlocked: function (callback) { + invokeWhenHeapUnlocked: function(callback) { // This is somewhat like a sync context. If we're not locked, just pass through the call directly. if (!currentHeapLock) { callback(); From 56dc6370fcb33e06c83bb43e8bd03cfe72a6b1f9 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 7 Feb 2023 09:44:14 +0100 Subject: [PATCH 6/6] feedback --- .../WebAssembly/src/Services/LazyAssemblyLoader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs index bc94c8b96f93..3cff52948eb1 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs +++ b/src/Components/WebAssembly/WebAssembly/src/Services/LazyAssemblyLoader.cs @@ -115,8 +115,8 @@ private async Task LoadAssembly(string assemblyToLoad, List loadedAsse { using var files = await LazyAssemblyLoaderInterop.LoadLazyAssembly(assemblyToLoad); - byte[] dllBytes = files.GetPropertyAsByteArray("dll")!; - byte[]? pdbBytes = files.GetPropertyAsByteArray("pdb"); + var dllBytes = files.GetPropertyAsByteArray("dll")!; + var pdbBytes = files.GetPropertyAsByteArray("pdb"); Assembly loadedAssembly = pdbBytes == null ? AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes)) : AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes), new MemoryStream(pdbBytes));