maui icon indicating copy to clipboard operation
maui copied to clipboard

CSS hot reload fails in .NET MAUI Blazor app after 2nd edit

Open danroth27 opened this issue 2 years ago • 18 comments

Repro steps:

  • VS: 17.3 P6
  • Create a new .NET MAUI Blazor app
  • Edit app.css
  • Save to hot reload the change
  • Edit app.css again

Expected result: 2nd edit is successfully applied

Actual result:

  • No UI update
  • Error in Hot Reload output window: "Applying changes to app.css failed. The process cannot access the file 'C:\Users\user\source\repos\MauiApp1\MauiApp1\wwwroot\css\app.css' because it is being used by another process."

Process Explorer shows that the app is holding onto the file: image

@TanayParikh @mkArtakMSFT @mcumming

This issue is similar to the CSS hot reload issue with WinForms, but the behavior is different and the way Blazor handles the file stream is different on .NET MAUI which should avoid the WebView2 locking issue. In this case it seems like Blazor or .NET MAUI may be the culprit.

danroth27 avatar Aug 04 '22 18:08 danroth27

This may just require closing out the content stream after it's been copied:

https://github.com/dotnet/maui/blob/d94a1ad7d8d8d8e2b2bf1a46009955f20762a638/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs#L86-L91

TanayParikh avatar Aug 04 '22 19:08 TanayParikh

@danroth27 I'm unable to repro this, did you have any other steps you'd recommend trying?

image

TanayParikh avatar Aug 04 '22 22:08 TanayParikh

I ended up being able to repro using a clean maui-blazor app. Above screenshot is using the MAUI sample app in the maui repo.

I think this'll be resolved if we can resolve https://github.com/dotnet/maui/issues/9206, at which point, we'll likely end up running into https://github.com/MicrosoftEdge/WebView2Feedback/issues/2513 as we'd no longer be copying the content stream into a separate memory stream. Not the ideal resolution, but it would be good to get these related but different issues into the same "base" issue.

TanayParikh avatar Aug 04 '22 23:08 TanayParikh

https://github.com/dotnet/maui/pull/9254 has been merged. Once the builds for that are available, it would be good to revalidate this.

TanayParikh avatar Aug 08 '22 21:08 TanayParikh

it would be good to revalidate this.

Things should've now propagated. I've requested revalidation for this scenario using the latest (internal) builds.

TanayParikh avatar Aug 15 '22 23:08 TanayParikh

I tried to build a project in maui-blazor in 17.4 Preview 1. Changing CSS doesn't reflect in the running app. I am not sure if it's happening after the 2nd exit.

This is the stack track I receive from VS, I am running it in Windows machine (Same machine where VS is running)

StreamJsonRpc.RemoteInvocationException: The solution does not contain the specified document. at StreamJsonRpc.JsonRpc.<InvokeCoreAsync>d__1431.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result() at Microsoft.CodeAnalysis.Remote.BrokeredServiceConnection1.<TryInvokeAsync>d__201.MoveNext() RPC server exception: System.InvalidOperationException: The solution does not contain the specified document. at Microsoft.CodeAnalysis.Shared.Extensions.ISolutionExtensions.<GetRequiredDocumentAsync>d__9.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.CodeAnalysis.EditAndContinue.RemoteEditAndContinueService.<>c__DisplayClass9_0.<<GetDocumentDiagnosticsAsync>b__0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result() at Microsoft.CodeAnalysis.Remote.RemoteWorkspace.<>c__DisplayClass10_01.<<RunWithSolutionAsync>g__TryFastGetSolutionAndRunAsync|0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result() at Microsoft.CodeAnalysis.Remote.RemoteWorkspace.<RunWithSolutionAsync>d__101.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result() at Microsoft.CodeAnalysis.Remote.BrokeredServiceBase.<RunWithSolutionAsync>d__111.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.ValueTask1.get_Result() at Microsoft.CodeAnalysis.Remote.BrokeredServiceBase.<RunServiceImplAsync>d__141.MoveNext()

anirugu avatar Aug 16 '22 05:08 anirugu

@anirugu that appears to be a different issue. The issue we're discussing here doesn't explicitly throw an exception as far as I know. Based on the stack trace you provided, I suspect you may be running into https://github.com/dotnet/sdk/issues/26762 which we're in the middle of patching.

TanayParikh avatar Aug 16 '22 15:08 TanayParikh

it would be good to revalidate this.

Things should've now propagated. I've requested revalidation for this scenario using the latest (internal) builds.

Unfortunately, the issue seems to continue to reproduce despite the recent changes.

fyi/ @javiercn

TanayParikh avatar Aug 16 '22 23:08 TanayParikh

Adding to RC2 milestone.

TanayParikh avatar Aug 16 '22 23:08 TanayParikh

@javiercn could this have any relation to https://github.com/dotnet/sdk/issues/26762 / https://github.com/dotnet/sdk/pull/26765 / https://github.com/dotnet/sdk/pull/27102?

@danroth27 just confirming your issue here was on .NET 6?

TanayParikh avatar Aug 16 '22 23:08 TanayParikh

Reopening as @jinzhao1127 is still repro'ing this issue. https://github.com/dotnet/maui/pull/9645 should've resolved this. Specifically:

https://github.com/dotnet/maui/pull/9645/files#diff-5cf51db2a43b59a7b8ce04f82cc5e21e2e57a2eeba4b02b5aae132f1dc086820R70

TanayParikh avatar Aug 31 '22 21:08 TanayParikh

I haven't been able to repro this given I'm running into https://github.com/aspnet/AspNetCore-ManualTests/issues/1525 first. Will have to hold off on further investigation here till https://github.com/aspnet/AspNetCore-ManualTests/issues/1525 is resolved.

TanayParikh avatar Aug 31 '22 21:08 TanayParikh

@mcumming pointed out the following discrepency:

image

vs. in the VS Hot reload output:

14:01 46.51 MauiApp14: [Warning] Endpoint has unsupported platform WinUI for .NET Hot Reload, skipping.
14:01 46.57 MauiApp14: Hot Reload session started
14:01 55.73 MauiApp14: Applying the changes to app.css to the running application
14:02 00.63 MauiApp14: Applying the changes to app.css to the running application
14:02 03.57 MauiApp14: Applying changes to app.css failed. The process cannot access the file 'C:\Users\taparik\source\repos\MauiApp14\MauiApp14\wwwroot\css\app.css' because it is being used by another process.

Notice the difference in path.

TanayParikh avatar Oct 13 '22 21:10 TanayParikh

Making this change:

image

here:

https://github.com/dotnet/maui/blob/8a9088f1e433f3f35915bf5debf0426fe21c42d0/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs#L105-L113

results in Process Explorer reporting no processes holding the app.css handle:

image

However, hot reload still fails on:

16:27 36.93 MauiApp14: Applying changes to app.css failed. The process cannot access the file 'C:\Users\taparik\source\repos\MauiApp14\MauiApp14\wwwroot\css\app.css' because it is being used by another process.

Given this is a distinctly different file from what was being reported by Process Explorer (see above post), I think we may actually have two separate bugs here. One would be resolved by the code change above, while there appears to be another bug that's resulting in the underlying failed hot reload issue persisting.

Note, @MackinnonBuck was able to confirm, it does in fact repro on Android (thanks Mackinnon!). So this definitely doesn't appear to be platform specific.

@mcumming why is this reading from the project folder, whereas we're performing hot reload from the packaged app (screenshot below). (cc/ @javiercn as I believe he may have worked with packaging in this context).

image

TanayParikh avatar Oct 13 '22 23:10 TanayParikh

@TanayParikh For MAUI we read from the project folder because that is the file that the user is modifying. The instance of that file in the packaged folder is not updated that I know of after the initial build. That is why for content files HotReload sends the entire contents of the file to the agent in the running application.

mcumming avatar Oct 14 '22 03:10 mcumming

Thanks for clarifying. What's unclear in that case is what is actually holding on to the file handle. Nothing shows up in process explorer.

Did you have a chance to experiment with alternatives to the current File.ReadAllBytes in UITools? Perhaps we could try to open a file stream (with file sharing explicitly configured) and then copy to a memory stream to see if that potentially results in different behavior?

TanayParikh avatar Oct 14 '22 07:10 TanayParikh

Yes, I switched the File.ReadAllBytes to explicitly openening the file with using var stream = new (fullPathToCssFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);, unfortunately it hasn't had an effect on this issue.

mcumming avatar Oct 14 '22 13:10 mcumming

We're trying out a temporary mitigation of this within VS at the moment.

TanayParikh avatar Oct 26 '22 23:10 TanayParikh

Closing this, as a mitigation from @mcumming has landed already. Basically, the mitigation is a retry on the VS side, which seems to work. we still don't know why exactly this was happening, but to timebox the investigation going to move forward with the mitigation for now. Michael will file a follow-up backlog issue to track the underlying issue for future resolution.

mkArtakMSFT avatar Feb 02 '23 19:02 mkArtakMSFT