Skip to content

[WPF] Fix BlazorWebView disposal hanging when cleanup awaits JS interop - #39497

Merged
kubaflo merged 1 commit into
dotnet:inflight/currentfrom
sheiksyedm:sheiksyedm-maui-issue-39471
Oct 20, 2026
Merged

kubaflo merged 1 commit into
dotnet:inflight/currentfrom
sheiksyedm:sheiksyedm-maui-issue-39471

Conversation

@sheiksyedm

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Issue details

On WPF, awaiting BlazorWebView.DisposeAsync() can hang when a Razor component or scoped service awaits JavaScript interop during its asynchronous disposal.

For example, a scoped service implementing IAsyncDisposable can await IJSRuntime.InvokeVoidAsync during cleanup. The same problem affects components that perform asynchronous JS cleanup, such as disposing an IJSObjectReference module.

The disposal-time JS invocation is silently dropped rather than completed or faulted. Consequently, the component or service cannot finish disposal, and the owning BlazorWebView.DisposeAsync() remains incomplete. Catching JSDisconnectedException does not help because no such exception is raised by this path.

The reported real-world scenario involves closing a WPF dialog containing a DevExpress Blazor component whose scoped service releases JS modules during disposal.

Root cause

WPF's BlazorWebView.DisposeAsync() calls _webviewManager.MarkAsDisposing() before disposing the page through the WebView manager.

That flag causes WebView2WebViewManager.SendMessage() to return without sending messages. However, page disposal still needs to dispose the Razor renderer and scoped services, and their cleanup code can await JS interop.

This ordering blocks the JS invocation that disposal itself is waiting to complete:

  1. The control marks the manager as disposing.
  2. Page disposal invokes component or scoped-service cleanup.
  3. Cleanup awaits a JS interop call.
  4. SendMessage() drops the outgoing invocation because the manager is already marked as disposing.
  5. Cleanup cannot finish, so control disposal cannot finish either.

Additionally, the existing ConfigureAwait(false) can move native WebView cleanup off the WPF UI thread when manager disposal completes asynchronously.

Fix description

  • Keep JS messaging available while awaiting WebView manager disposal, allowing component and scoped-service JS cleanup to complete.
  • Call MarkAsDisposing() after manager/page disposal completes and before disposing the native WebView.
  • Use ConfigureAwait(true) to preserve the WPF UI context for native WebView disposal.
  • Update the shared manager's documentation to describe the required disposal order.

The existing late-message guards in SendMessage() remain in place. The control's _isDisposed guard is also retained.

The functional change is limited to the WPF BlazorWebView implementation. No MAUI handler behavior is changed.

Why no automated regression test is included

No existing automated tests targeting the WPF BlazorWebView implementation were found in this repository. The existing BlazorWebView unit and device test projects target the MAUI implementation; the WPF application is a sample rather than an automated test suite.

A representative regression test would require a WPF host running on an STA/UI dispatcher with a real WebView2 instance and JS interop. This PR does not introduce a new WPF test project or test infrastructure. Adding a MAUI test would not cover the affected WPF disposal path.

Instead, the fix was verified using a separate executable WPF reproduction harness. That harness and the MAUI Sandbox comparison changes are not included in this PR.

Verification

Verified locally on Windows 11 with a real WebView2 runtime, using both the reported package version (10.0.110) and source-built WPF libraries.

The WPF reproduction initializes Blazor, instantiates the scoped service, and successfully completes a JS preflight call before disposing the control on the WPF UI thread. A bounded 10-second observation distinguishes completed disposal from the reported hang.

Scenario Before fix After fix
Scoped service awaits JS during disposal Service entered disposal, but its JS call and control disposal remained incomplete after 10 seconds JS call, service disposal, and control disposal completed
Razor component awaits JS during disposal Component entered disposal, but its JS call and control disposal remained incomplete after 10 seconds JS call, component disposal, and control disposal completed
Scoped service disposes without calling JS Disposal completed Disposal completed

All three scenarios completed successfully in three repeated runs each against the patched source-built WPF library. Subsequent runs of the local verification script also passed.

Issues Fixed

Fixes #39471

Keep JS messaging available until component and scoped service disposal completes, then suppress messages before disposing the native WebView. Preserve the WPF UI context for native cleanup.

Fixes dotnet#39471

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 20, 2026 11:30
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 39497

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 39497"

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Oct 20, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

@sheiksyedm sheiksyedm added area-blazor Blazor Hybrid / Desktop, BlazorWebView community ✨ Community Contribution labels Oct 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The native WPF/WebView2 lifecycle change needs completed CI and human confirmation of the reported runtime verification.

No open issues 🎉

What changed in this PR

Fixes the WPF BlazorWebView disposal hang described in #39471 by keeping JavaScript interop available during component and scoped-service cleanup.

Changes:

  • Delays message shutdown until manager disposal completes.
  • Preserves the WPF UI context for native WebView disposal.
  • Updates shared documentation to describe the disposal order; MAUI handler behavior is unchanged.
File Description
src/​BlazorWebView/​src/​Wpf/​BlazorWebView.cs Reorders disposal and preserves the UI context.
src/​BlazorWebView/​src/​SharedSource/​WebView2WebViewManager.cs Updates disposal-order documentation only.

Review effort: Balanced

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Oct 20, 2026
@kubaflo

This comment has been minimized.

@azure-pipelines

This comment has been minimized.

@kubaflo
kubaflo changed the base branch from main to inflight/current October 20, 2026 22:41
@kubaflo
kubaflo merged commit ce33c7b into dotnet:inflight/current Oct 20, 2026
182 of 213 checks passed
kubaflo pushed a commit that referenced this pull request Oct 21, 2026
…op (#39497)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue details

On WPF, awaiting `BlazorWebView.DisposeAsync()` can hang when a Razor
component or scoped service awaits JavaScript interop during its
asynchronous disposal.

For example, a scoped service implementing `IAsyncDisposable` can await
`IJSRuntime.InvokeVoidAsync` during cleanup. The same problem affects
components that perform asynchronous JS cleanup, such as disposing an
`IJSObjectReference` module.

The disposal-time JS invocation is silently dropped rather than
completed or faulted. Consequently, the component or service cannot
finish disposal, and the owning `BlazorWebView.DisposeAsync()` remains
incomplete. Catching `JSDisconnectedException` does not help because no
such exception is raised by this path.

The reported real-world scenario involves closing a WPF dialog
containing a DevExpress Blazor component whose scoped service releases
JS modules during disposal.

### Root cause

WPF's `BlazorWebView.DisposeAsync()` calls
`_webviewManager.MarkAsDisposing()` before disposing the page through
the WebView manager.

That flag causes `WebView2WebViewManager.SendMessage()` to return
without sending messages. However, page disposal still needs to dispose
the Razor renderer and scoped services, and their cleanup code can await
JS interop.

This ordering blocks the JS invocation that disposal itself is waiting
to complete:

1. The control marks the manager as disposing.
2. Page disposal invokes component or scoped-service cleanup.
3. Cleanup awaits a JS interop call.
4. `SendMessage()` drops the outgoing invocation because the manager is
already marked as disposing.
5. Cleanup cannot finish, so control disposal cannot finish either.

Additionally, the existing `ConfigureAwait(false)` can move native
WebView cleanup off the WPF UI thread when manager disposal completes
asynchronously.

### Fix description

- Keep JS messaging available while awaiting WebView manager disposal,
allowing component and scoped-service JS cleanup to complete.
- Call `MarkAsDisposing()` after manager/page disposal completes and
before disposing the native WebView.
- Use `ConfigureAwait(true)` to preserve the WPF UI context for native
WebView disposal.
- Update the shared manager's documentation to describe the required
disposal order.

The existing late-message guards in `SendMessage()` remain in place. The
control's `_isDisposed` guard is also retained.

The functional change is limited to the WPF BlazorWebView
implementation. No MAUI handler behavior is changed.

### Why no automated regression test is included

No existing automated tests targeting the WPF BlazorWebView
implementation were found in this repository. The existing BlazorWebView
unit and device test projects target the MAUI implementation; the WPF
application is a sample rather than an automated test suite.

A representative regression test would require a WPF host running on an
STA/UI dispatcher with a real WebView2 instance and JS interop. This PR
does not introduce a new WPF test project or test infrastructure. Adding
a MAUI test would not cover the affected WPF disposal path.

Instead, the fix was verified using a separate executable WPF
reproduction harness. That harness and the MAUI Sandbox comparison
changes are not included in this PR.

### Verification

Verified locally on Windows 11 with a real WebView2 runtime, using both
the reported package version (`10.0.110`) and source-built WPF
libraries.

The WPF reproduction initializes Blazor, instantiates the scoped
service, and successfully completes a JS preflight call before disposing
the control on the WPF UI thread. A bounded 10-second observation
distinguishes completed disposal from the reported hang.

| Scenario | Before fix | After fix |
| --- | --- | --- |
| Scoped service awaits JS during disposal | Service entered disposal,
but its JS call and control disposal remained incomplete after 10
seconds | JS call, service disposal, and control disposal completed |
| Razor component awaits JS during disposal | Component entered
disposal, but its JS call and control disposal remained incomplete after
10 seconds | JS call, component disposal, and control disposal completed
|
| Scoped service disposes without calling JS | Disposal completed |
Disposal completed |

All three scenarios completed successfully in three repeated runs each
against the patched source-built WPF library. Subsequent runs of the
local verification script also passed.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #39471

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Oct 25, 2026
…op (#39497)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue details

On WPF, awaiting `BlazorWebView.DisposeAsync()` can hang when a Razor
component or scoped service awaits JavaScript interop during its
asynchronous disposal.

For example, a scoped service implementing `IAsyncDisposable` can await
`IJSRuntime.InvokeVoidAsync` during cleanup. The same problem affects
components that perform asynchronous JS cleanup, such as disposing an
`IJSObjectReference` module.

The disposal-time JS invocation is silently dropped rather than
completed or faulted. Consequently, the component or service cannot
finish disposal, and the owning `BlazorWebView.DisposeAsync()` remains
incomplete. Catching `JSDisconnectedException` does not help because no
such exception is raised by this path.

The reported real-world scenario involves closing a WPF dialog
containing a DevExpress Blazor component whose scoped service releases
JS modules during disposal.

### Root cause

WPF's `BlazorWebView.DisposeAsync()` calls
`_webviewManager.MarkAsDisposing()` before disposing the page through
the WebView manager.

That flag causes `WebView2WebViewManager.SendMessage()` to return
without sending messages. However, page disposal still needs to dispose
the Razor renderer and scoped services, and their cleanup code can await
JS interop.

This ordering blocks the JS invocation that disposal itself is waiting
to complete:

1. The control marks the manager as disposing.
2. Page disposal invokes component or scoped-service cleanup.
3. Cleanup awaits a JS interop call.
4. `SendMessage()` drops the outgoing invocation because the manager is
already marked as disposing.
5. Cleanup cannot finish, so control disposal cannot finish either.

Additionally, the existing `ConfigureAwait(false)` can move native
WebView cleanup off the WPF UI thread when manager disposal completes
asynchronously.

### Fix description

- Keep JS messaging available while awaiting WebView manager disposal,
allowing component and scoped-service JS cleanup to complete.
- Call `MarkAsDisposing()` after manager/page disposal completes and
before disposing the native WebView.
- Use `ConfigureAwait(true)` to preserve the WPF UI context for native
WebView disposal.
- Update the shared manager's documentation to describe the required
disposal order.

The existing late-message guards in `SendMessage()` remain in place. The
control's `_isDisposed` guard is also retained.

The functional change is limited to the WPF BlazorWebView
implementation. No MAUI handler behavior is changed.

### Why no automated regression test is included

No existing automated tests targeting the WPF BlazorWebView
implementation were found in this repository. The existing BlazorWebView
unit and device test projects target the MAUI implementation; the WPF
application is a sample rather than an automated test suite.

A representative regression test would require a WPF host running on an
STA/UI dispatcher with a real WebView2 instance and JS interop. This PR
does not introduce a new WPF test project or test infrastructure. Adding
a MAUI test would not cover the affected WPF disposal path.

Instead, the fix was verified using a separate executable WPF
reproduction harness. That harness and the MAUI Sandbox comparison
changes are not included in this PR.

### Verification

Verified locally on Windows 11 with a real WebView2 runtime, using both
the reported package version (`10.0.110`) and source-built WPF
libraries.

The WPF reproduction initializes Blazor, instantiates the scoped
service, and successfully completes a JS preflight call before disposing
the control on the WPF UI thread. A bounded 10-second observation
distinguishes completed disposal from the reported hang.

| Scenario | Before fix | After fix |
| --- | --- | --- |
| Scoped service awaits JS during disposal | Service entered disposal,
but its JS call and control disposal remained incomplete after 10
seconds | JS call, service disposal, and control disposal completed |
| Razor component awaits JS during disposal | Component entered
disposal, but its JS call and control disposal remained incomplete after
10 seconds | JS call, component disposal, and control disposal completed
|
| Scoped service disposes without calling JS | Disposal completed |
Disposal completed |

All three scenarios completed successfully in three repeated runs each
against the patched source-built WPF library. Subsequent runs of the
local verification script also passed.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #39471

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
kubaflo pushed a commit that referenced this pull request Oct 26, 2026
…op (#39497)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue details

On WPF, awaiting `BlazorWebView.DisposeAsync()` can hang when a Razor
component or scoped service awaits JavaScript interop during its
asynchronous disposal.

For example, a scoped service implementing `IAsyncDisposable` can await
`IJSRuntime.InvokeVoidAsync` during cleanup. The same problem affects
components that perform asynchronous JS cleanup, such as disposing an
`IJSObjectReference` module.

The disposal-time JS invocation is silently dropped rather than
completed or faulted. Consequently, the component or service cannot
finish disposal, and the owning `BlazorWebView.DisposeAsync()` remains
incomplete. Catching `JSDisconnectedException` does not help because no
such exception is raised by this path.

The reported real-world scenario involves closing a WPF dialog
containing a DevExpress Blazor component whose scoped service releases
JS modules during disposal.

### Root cause

WPF's `BlazorWebView.DisposeAsync()` calls
`_webviewManager.MarkAsDisposing()` before disposing the page through
the WebView manager.

That flag causes `WebView2WebViewManager.SendMessage()` to return
without sending messages. However, page disposal still needs to dispose
the Razor renderer and scoped services, and their cleanup code can await
JS interop.

This ordering blocks the JS invocation that disposal itself is waiting
to complete:

1. The control marks the manager as disposing.
2. Page disposal invokes component or scoped-service cleanup.
3. Cleanup awaits a JS interop call.
4. `SendMessage()` drops the outgoing invocation because the manager is
already marked as disposing.
5. Cleanup cannot finish, so control disposal cannot finish either.

Additionally, the existing `ConfigureAwait(false)` can move native
WebView cleanup off the WPF UI thread when manager disposal completes
asynchronously.

### Fix description

- Keep JS messaging available while awaiting WebView manager disposal,
allowing component and scoped-service JS cleanup to complete.
- Call `MarkAsDisposing()` after manager/page disposal completes and
before disposing the native WebView.
- Use `ConfigureAwait(true)` to preserve the WPF UI context for native
WebView disposal.
- Update the shared manager's documentation to describe the required
disposal order.

The existing late-message guards in `SendMessage()` remain in place. The
control's `_isDisposed` guard is also retained.

The functional change is limited to the WPF BlazorWebView
implementation. No MAUI handler behavior is changed.

### Why no automated regression test is included

No existing automated tests targeting the WPF BlazorWebView
implementation were found in this repository. The existing BlazorWebView
unit and device test projects target the MAUI implementation; the WPF
application is a sample rather than an automated test suite.

A representative regression test would require a WPF host running on an
STA/UI dispatcher with a real WebView2 instance and JS interop. This PR
does not introduce a new WPF test project or test infrastructure. Adding
a MAUI test would not cover the affected WPF disposal path.

Instead, the fix was verified using a separate executable WPF
reproduction harness. That harness and the MAUI Sandbox comparison
changes are not included in this PR.

### Verification

Verified locally on Windows 11 with a real WebView2 runtime, using both
the reported package version (`10.0.110`) and source-built WPF
libraries.

The WPF reproduction initializes Blazor, instantiates the scoped
service, and successfully completes a JS preflight call before disposing
the control on the WPF UI thread. A bounded 10-second observation
distinguishes completed disposal from the reported hang.

| Scenario | Before fix | After fix |
| --- | --- | --- |
| Scoped service awaits JS during disposal | Service entered disposal,
but its JS call and control disposal remained incomplete after 10
seconds | JS call, service disposal, and control disposal completed |
| Razor component awaits JS during disposal | Component entered
disposal, but its JS call and control disposal remained incomplete after
10 seconds | JS call, component disposal, and control disposal completed
|
| Scoped service disposes without calling JS | Disposal completed |
Disposal completed |

All three scenarios completed successfully in three repeated runs each
against the patched source-built WPF library. Subsequent runs of the
local verification script also passed.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #39471

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
github-actions Bot pushed a commit that referenced this pull request Oct 28, 2026
…op (#39497)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issue details

On WPF, awaiting `BlazorWebView.DisposeAsync()` can hang when a Razor
component or scoped service awaits JavaScript interop during its
asynchronous disposal.

For example, a scoped service implementing `IAsyncDisposable` can await
`IJSRuntime.InvokeVoidAsync` during cleanup. The same problem affects
components that perform asynchronous JS cleanup, such as disposing an
`IJSObjectReference` module.

The disposal-time JS invocation is silently dropped rather than
completed or faulted. Consequently, the component or service cannot
finish disposal, and the owning `BlazorWebView.DisposeAsync()` remains
incomplete. Catching `JSDisconnectedException` does not help because no
such exception is raised by this path.

The reported real-world scenario involves closing a WPF dialog
containing a DevExpress Blazor component whose scoped service releases
JS modules during disposal.

### Root cause

WPF's `BlazorWebView.DisposeAsync()` calls
`_webviewManager.MarkAsDisposing()` before disposing the page through
the WebView manager.

That flag causes `WebView2WebViewManager.SendMessage()` to return
without sending messages. However, page disposal still needs to dispose
the Razor renderer and scoped services, and their cleanup code can await
JS interop.

This ordering blocks the JS invocation that disposal itself is waiting
to complete:

1. The control marks the manager as disposing.
2. Page disposal invokes component or scoped-service cleanup.
3. Cleanup awaits a JS interop call.
4. `SendMessage()` drops the outgoing invocation because the manager is
already marked as disposing.
5. Cleanup cannot finish, so control disposal cannot finish either.

Additionally, the existing `ConfigureAwait(false)` can move native
WebView cleanup off the WPF UI thread when manager disposal completes
asynchronously.

### Fix description

- Keep JS messaging available while awaiting WebView manager disposal,
allowing component and scoped-service JS cleanup to complete.
- Call `MarkAsDisposing()` after manager/page disposal completes and
before disposing the native WebView.
- Use `ConfigureAwait(true)` to preserve the WPF UI context for native
WebView disposal.
- Update the shared manager's documentation to describe the required
disposal order.

The existing late-message guards in `SendMessage()` remain in place. The
control's `_isDisposed` guard is also retained.

The functional change is limited to the WPF BlazorWebView
implementation. No MAUI handler behavior is changed.

### Why no automated regression test is included

No existing automated tests targeting the WPF BlazorWebView
implementation were found in this repository. The existing BlazorWebView
unit and device test projects target the MAUI implementation; the WPF
application is a sample rather than an automated test suite.

A representative regression test would require a WPF host running on an
STA/UI dispatcher with a real WebView2 instance and JS interop. This PR
does not introduce a new WPF test project or test infrastructure. Adding
a MAUI test would not cover the affected WPF disposal path.

Instead, the fix was verified using a separate executable WPF
reproduction harness. That harness and the MAUI Sandbox comparison
changes are not included in this PR.

### Verification

Verified locally on Windows 11 with a real WebView2 runtime, using both
the reported package version (`10.0.110`) and source-built WPF
libraries.

The WPF reproduction initializes Blazor, instantiates the scoped
service, and successfully completes a JS preflight call before disposing
the control on the WPF UI thread. A bounded 10-second observation
distinguishes completed disposal from the reported hang.

| Scenario | Before fix | After fix |
| --- | --- | --- |
| Scoped service awaits JS during disposal | Service entered disposal,
but its JS call and control disposal remained incomplete after 10
seconds | JS call, service disposal, and control disposal completed |
| Razor component awaits JS during disposal | Component entered
disposal, but its JS call and control disposal remained incomplete after
10 seconds | JS call, component disposal, and control disposal completed
|
| Scoped service disposes without calling JS | Disposal completed |
Disposal completed |

All three scenarios completed successfully in three repeated runs each
against the patched source-built WPF library. Subsequent runs of the
local verification script also passed.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #39471

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
copilot-pat-pool — 9d2b1038 Deployed Oct 20, 2026 by sheiksyedm via conclusion #2413
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Blazor Hybrid / Desktop, BlazorWebView community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-review-in-progress AI review is currently running for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WPF] BlazorWebView.DisposeAsync never completes when a scoped service or component awaits JS interop on disposal

3 participants