-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Window freezes during resize when updating WriteableBitmap from worker thread #5816
Comments
@andrekoehler See #4396 And I fixed it in #4425 And, I publish the CustomWPF nuget in https://www.nuget.org/packages/Lindexi.Src.CustomWPF/1.0.3 And I write a demo code with your demo repo, see https://github.com/lindexi/lindexi_gd/tree/c81be0e0fc06b3df9504c7ff44d7377ac5b26b55/BitmapSourceTest You should publish the demo with x86 and run the application in BitmapSourceTest\bin\Debug\net6.0-windows\win-x86\publish\BitmapSourceTest.exe dotnet publish -r win-x86 --self-contained Could you test the demo code? |
Well the example on the same page you cited does not really suggest it is safe to allow other dispatcher operations during the lock. You might want to prepare your frame in another buffer and then perform just a memory copy inside the lock on UI thread. Alternatively, in case tearing was not an issue for your application, you might not need to keep the bitmap locked, only lock it for obtaining the |
I'm using a very similar design to this example (although using a timer rather than a loop), I sometimes experience the same issue. Is there an alternative control we should be using? @andrekoehler Did you by chance find a solution? |
@andrekoehler I actually did some tests last night, moved all rendering code to the UI thread (Diapatcher.Invoked the whole thing) and I still get freezes. I need to do more testing, it might be specific to low core count or an older framework version as it's only happening on an old laptop now though without getting to the bottom of it I can't be sure it won't happen on modern machines too. Resizing a grid splitter also triggers the issue. |
I changed my ui structure to be more like the example here, using an Image instead of Rectangle/ImageBrush: <Windows:Visualization>
- <Rectangle>
- <Rectangle.Resources>
- <LocalWindows:SpectrogramRenderer x:Key="Renderer"
- Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LocalWindows:Spectrogram}}}"
- Height="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LocalWindows:Spectrogram}}}"
- Color="{Binding Foreground, Converter={StaticResource BrushConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LocalWindows:Spectrogram}}}"></LocalWindows:SpectrogramRenderer>
- </Rectangle.Resources>
- <Rectangle.Fill>
- <ImageBrush ImageSource="{Binding Bitmap, Source={StaticResource Renderer}}" Viewbox="{Binding Viewbox, Source={StaticResource Renderer}}" ViewboxUnits="Absolute"></ImageBrush>
- </Rectangle.Fill>
- </Rectangle>
+ <Border>
+ <Image>
+ <Image.Resources>
+ <LocalWindows:SpectrogramRenderer x:Key="Renderer"
+ Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Border}}}"
+ Height="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Border}}}"
+ Color="{Binding Foreground, Converter={StaticResource BrushConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type LocalWindows:Spectrogram}}}"></LocalWindows:SpectrogramRenderer>
+ </Image.Resources>
+ <Image.Source>
+ <Binding Source="{StaticResource Renderer}" Path="Bitmap"></Binding>
+ </Image.Source>
+ </Image>
+ </Border>
</Windows:Visualization> This, combined with doing all rendering on the UI thread fixed the issue. Window and Grid resize no longer freezes. Additionally my TabControl issue was also fixed (I suspected it was the same cause). Unfortunately the performance is really bad, from 0.5% CPU to basically maxing out a core. |
@Aidan-G I worry about your problem for a different reason than this issues |
I had a similar problem, was able to get past it by locking the bitmap only to grab data or to update the dirty rectangle. This goes against the workflow written here: https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.writeablebitmap?view=windowsdesktop-7.0 ; But it works without tearing (afaict),
|
Copying the data on the UI thread is not a good idea IMO. For 4k video the mem copy alone takes 15 milliseconds, so that means 45% of the time your UI thread would be locked. UI thread should be locked 0% of the time. Not to mention, what is the point of a "Lock" feature that only works on one thread. Maybe for WPF threads? Idk, just seems weird to me. |
Its great that this worked for you, but I'm a bit concerned because this is explicitly forbidden here: "Update the back buffer only between calls to the Lock and Unlock methods. If you do not follow the Lock/Unlock workflow described in the WriteableBitmap class remarks, undefined behaviors, such as tearing, can occur." source |
I absolutely agree with you. |
After almost three years I looked at this issue again. On .NET 8 it still occurs with my code, but if I add Thread.Sleep(1) to the background thread loop the issue goes away, so I would assume the issue is caused by overloading the UI thread with work. |
.NET Core Version: (e.g. 3.0 Preview1, or daily build number, use
dotnet --info
)6.0.100
Windows version: (
winver
)Windows 10 21H2
Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes/No
Yes
Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? If yes, please file the issue via the instructions here.
No
Problem description:
Updating the back buffer of a WriteableBitmap once per frame works fine until I try to resize the form. As soon as I do that, the mouse cursor is forever in resize mode and the mouse is locked out from the Windows task bar.
Actual behavior:
Stuck in resize mode, Window does not respond anymore.
Expected behavior:
Writing to a WriteableBitmap should not disturb the Window's resizing behavior because it was explicitly designed for multi-threading: https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.writeablebitmap?view=windowsdesktop-6.0&viewFallbackFrom=net-6.0#remarks
Minimal repro:
Create a new Wpf App, then copy the following code over MainWindow.xaml.cs:
The text was updated successfully, but these errors were encountered: