我在WPF中遇到问题,在关闭之后,在应用程序的另一部分尝试写入图像之前,窗口不会在背景图像文件上释放它的文件锁定。
以此为例;说我有一个WPF应用程序,包括3个窗口,1个“菜单”选择窗口和另外2个。这两个窗口使用ImageBrush
作为BitmapImage
(相同的图片)创建ImageSource
。
窗口A有一个按钮,当按下该按钮时,通过将可用背景图像复制到用作原始ImageSource
的文件并创建新ImageBrush
并设置Window.Background
来循环显示这些图像。到新画笔。
Window B只使用ImageBrush
绘制Window.Background
。
如果启动了窗口A,背景切换,关闭然后启动了窗口B,一切都很好。
如果Window B启动,关闭,则启动Window A并且背景切换它崩溃。尝试切换背景会引发IOException
因为:
“进程无法访问文件'C:\ Backgrounds \ Background.png',因为它正由另一个进程使用。”
所以Window B仍然必须以某种方式抓住它!?我试过做一个GC.Collect(); GC.WaitForPendingFinalizers();
看看是否可以解决这个问题,但事实并非如此。
答案 0 :(得分:4)
Thomas给出的答案是正确的,如果您有文件路径,不想缓存位图,并且不想使用XAML,那么效果很好。
然而,还应该提到BitmapImage有一种通过设置BitmapCacheOption立即加载位图的内置方法:
BitmapImage img = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
img.BeginInit();
img.UriSource = imageUrl;
img.EndInit();
或
<BitmapImage CacheOption="OnLoad" UriSource="..." />
这将立即加载位图并显式关闭流,就像使用FileStream一样,但存在一些差异:
答案 1 :(得分:2)
我假设您直接从文件中加载图片,就像那样?
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = imageUrl;
img.EndInit();
尝试从流中加载它;这样你就可以在加载图像后自己关闭流,这样文件就不会被锁定:
BitmapImage img = new BitmapImage();
using (FileStream fs = File.OpenRead(imageFilePath)
{
img.BeginInit();
img.StreamSource = fs;
img.EndInit();
}