dotnet / dotnet/wpf

OperationPriorityChanged is raised without the new priority

Open
#9,148 6 comments 0 reactions 0 assignees View on GitHub
Bug Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

The dispatcher hook `OperationPriorityChanged` is called when the priority has not changed yet on the `DispatcherOperation`. It is already changed in the `PriorityQueue` of the dispatcher, but a subscriber of the event has no way of knowing this new priority.

### Reproduction Steps

Create a new WPF application
exchange contents of App.xaml.cs with
```CSHARP
using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;

namespace WpfApp
{
public partial class App : Application
{

protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

Dispatcher.Hooks.OperationPriorityChanged += (sender, args) =>
{
// Note that args.Operation.Priority is still Inactive here
Debugger.Break();
};

Action action = () => { };
var operation = Dispatcher.BeginInvoke(action, DispatcherPriority.Inactive);
operation.Priority = DispatcherPriority.Send;

}
}
}
```

### Expected behavior

I would expect the `OperationPriorityChanged` event to be called, when the priority change was completely finished.

### Actual behavior

The `OperationPriorityChanged` is called when the `DispatcherOperation` does not reflect the change.

### Regression?

I don't think so. This was probably designed this way.

### Known Workarounds

No workarounds.

### Impact

This is probably an edge case.
I am writing diagnostics for some dispatcher queue issues I am seeing in an application.
This makes it harder to debug. I probably will ignore dispatcher priority changes and just show diagnostics for the original Inactive state.

### Configuration

- .NET 8.0.5 (but I think this is not version dependent. Probably all versions since introduction of WPF)
- Windows 11
- x64
- It is not specific to this configuration

### Other information

When changing priority on `DispatcherOperation`, the operation tells it's dispatcher to move it to the new priority chain. The dispatcher will raise the event, and `DispatcherOperation` will change it's _priority field after the fact.
https://github.com/dotnet/wpf/blob/2b7d210c6669ab8c4779d9d5cc9216b05dff34a8/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherOperation.cs#L123-L126

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.