BitmapImage.UriSource锁定本地文件

时间:2016-11-16 22:15:36

标签: c# uwp

在我的UWP应用程序中,当Model层尝试更新(覆盖)文件时, 它会抛出UnauthorizedAccessException'访问被拒绝'异常,因为该文件被视图的 BitmapImage 锁定。

查看

var bitmap = new BitmapImage();
bitmap.UriSource = new Uri("ms-appdata:///local/image.jpg");

模型

private async UpdateImage()
{
   // this line throws!
   var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("image.jpg", CreationCollisionOption.ReplaceExisting);
   ...
}

如何阻止 BitmapImage 锁定用作 UriSource 的本地文件?

3 个答案:

答案 0 :(得分:0)

试试这个:

var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.CreateOption = BitmapCreateOptions.IgnoreImageCache;
bitmap.UriSource = new Uri("ms-appdata:///local/image.jpg");      
bitmap.EndInit();

答案 1 :(得分:0)

  

它抛出UnauthorizedAccessException'访问被拒绝'异常,因为该文件被View的BitmapImage锁定。

如您所知,如果使用BitmapImage.UriSource属性为BitmapImage设置源,则文件的文件流将处于锁定忙状态。为了解决这个问题,我们可以通过IRandomAccessStream自己读取文件流,在这种情况下,我们可以控制何时处理文件流以解锁文件。代码更新如下:

private async void btncreate_Click(object sender, RoutedEventArgs e)
{
    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("image.jpg", CreationCollisionOption.ReplaceExisting);
}

private async void Page_Loaded(object sender, RoutedEventArgs e)
{
    var bitmap = new BitmapImage();
    //bitmap.UriSource = new Uri("ms-appdata:///local/image.jpg");
    //imgshow.Source = bitmap;
    StorageFile imagefile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///local/image.jpg"));
    using (IRandomAccessStream stream = await imagefile.OpenAsync(FileAccessMode.Read))
    {
        bitmap.SetSource(stream);
        imgshow.Source = bitmap;
    } 
}

答案 2 :(得分:0)

“Sunteen Wu - MSFT”的解决方法几乎是正确的,因为bitmap.SetSource是隐式异步,流可能在SetSource完成之前被处理掉。您需要使用显式函数SetSourceAsync并等待它。

无论如何,这个解决方案使用了大量内存。 URI解决方案在某种程度上是内存友好的(很想知道为什么)。

URI解决方案将锁定文件一段时间不确定。虽然其他解决方案没有锁定任何文件,但它会在不合理的时间内分配大量内存。

我可以分享我的解决方案: 我将原始文件复制到临时文件夹,然后用相应的Uri打开它。但是这个文件不会被我删除,这可能会占用大量的磁盘空间。

有没有人有类似的问题?其他解决方案?