将“大”数据流设置为BitmapImage的源时出错

时间:2014-01-27 16:54:25

标签: c# exception windows-phone bitmapimage

我使用缓存机制,将图像保存到隔离存储并在下次加载,特别是在没有互联网连接的情况下。但是,它适用于小图像,但不适用于大约200kb的“大”图像。

这是我的代码:

public static object ExtractFromLocalStorage(Uri imageFileUri, string imageStorageFolder)
{
    var isolatedStoragePath = GetFileNameInIsolatedStorage(imageFileUri, imageStorageFolder);

    MemoryStream dataStream;
    using (var fileStream = Storage.OpenFile(isolatedStoragePath, FileMode.Open, FileAccess.Read))
    {
        if (fileStream.Length > int.MaxValue)
            return null;
        dataStream = new MemoryStream((int)fileStream.Length);
        var buffer = new byte[4096];
        while (dataStream.Length < fileStream.Length)
        {
            var readCount = fileStream.Read(buffer, 0, Math.Min(buffer.Length, (int)(fileStream.Length - dataStream.Length)));
            if (readCount <= 0)
            {
                throw new NotSupportedException();
            }
            dataStream.Write(buffer, 0, readCount);
        }
    }
    var bi = new BitmapImage();
    Deployment.Current.Dispatcher.BeginInvoke(() => bi.SetSource(dataStream));
    return bi;
}

小图片工作正常,但在加载此类200kb +图像时调用bi.SetSource时出现以下异常:     找不到该组件。 (HRESULT异常:0x88982F50)

我能做些什么吗? 200kb不是太大,文件保存得很好并且存在于本地。我希望有人可以帮助我,因为它是我应用程序的最后一个限制因素......:/

编辑(31月1日):

我重新开始,使用KawagoeToolkit库,我通过必要的方法扩展了我的应用程序。它运作良好,但我仍然想知道为什么上面给出了这样一个奇怪的例外。

1 个答案:

答案 0 :(得分:0)

不必使用调度员。它将介绍闭包语义。 在您的方法中,即使您处于另一个同步上下文中,它也没有意义。因为涉及的GUI线程没有任何内容。

无论如何,我已经测试了你的代码,但有一点不同 - 我使用的是StorageFile而不是IsolatedStorage。而且效果很好。

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        //622Kb: http://www.nasa.gov/sites/default/files/styles/1920x1080_autoletterbox/public/pia17147.jpg?itok=6jErm40V
        //2.7Mb: http://www.nasa.gov/sites/default/files/304_lunar_transit_14-00_ut_0.jpg
        StorageFile imageFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Assets\test3.jpg");
        MemoryStream mz;
        using (var z = await imageFile.OpenStreamForReadAsync())
        {
            if (z.Length > int.MaxValue) return;
            mz = new MemoryStream((int)z.Length);
            var buffer = new byte[4096];

            while (mz.Length < z.Length)
            {
                var readCount = z.Read(buffer, 0, Math.Min(buffer.Length, (int)(z.Length - mz.Length)));
                if (readCount <= 0)
                {
                    throw new NotSupportedException();
                }
                mz.Write(buffer, 0, readCount);
            }                
        }

        var bmp = new BitmapImage();
        bmp.SetSource(mz);
        //Deployment.Current.Dispatcher.BeginInvoke(() => img.Source = bmp); // if in another sync context only
        img.Source = bmp;
    }