我在 WPF 中遇到一个问题,在应用程序的另一部分尝试写入图像之前,窗口在关闭后不会释放它对背景图像文件的文件锁定。
举个例子;假设我有一个 WPF 应用程序,它由 3 个窗口、1 个“菜单”选择窗口和另外 2 个窗口组成。这两个窗口都使用 BitmapImage
作为 ImageSource
(相同 图像)创建一个 ImageBrush
。
窗口 A 有一个按钮,当按下该按钮时,通过将它们每个复制到用作原始 ImageSource
的文件并创建一个新的 ImageBrush
来循环显示可用的背景图像,并且将 Window.Background
设置为新画笔。
窗口 B 只是使用 ImageBrush
绘制 Window.Background
。
如果启动窗口 A,切换背景,关闭,然后启动窗口 B,一切都很好。
如果启动、关闭窗口 B,然后启动窗口 A 并切换背景,它就会崩溃。尝试切换背景会引发 IOException
,因为:
“该进程无法访问文件 'C:\Backgrounds\Background.png',因为它正被另一个进程使用。”
所以窗口 B 一定仍然以某种方式持有它!?我试过做一个 GC.Collect(); GC.WaitForPendingFinalizers();
看看是否可以解决问题,但事实并非如此。
最佳答案
Thomas 给出的答案是正确的,并且如果您有文件路径、不想缓存位图并且不想使用 XAML,则效果很好。
但是还应该提到的是,BitmapImage 有一个内置的方式来通过设置 BitmapCacheOption 立即加载位图:
BitmapImage img = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
img.BeginInit();
img.UriSource = imageUrl;
img.EndInit();
或
<BitmapImage CacheOption="OnLoad" UriSource="..." />
这将立即加载位图并显式关闭流,就像使用 FileStream 一样,但有几点不同:
- 它适用于任何 Uri,例如 pack://Uri。
- 它可以直接从 XAML 中使用
- 位图缓存在位图缓存中,因此以后使用相同的 Uri 不会转到磁盘。在您的特定应用程序中,这可能是一件坏事,但对于其他用途,它可能是一个理想的功能。
关于wpf - 删除窗口的背景图像 WPF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1661532/