2013-04-22 27 views
8

Trong ứng dụng của tôi, tôi đang sử dụng phương pháp trợ giúp được đề cập dưới đây để gắn hình ảnh lưu trữ Riêng biệt của tôi vào Điều khiển hình ảnh. Tôi nhận được phương pháp này helper từ liên kết "Binding Image stored in the Isolated Storage to Image Control in Windows Phone"Lỗi ứng dụng trong khi cố gắng ràng buộc Hình ảnh lưu trữ riêng biệt

public class IsoStoreImageSource : DependencyObject 
{ 
public static void SetIsoStoreFileName(UIElement element, string value) 
{ 
    element.SetValue(IsoStoreFileNameProperty, value); 
} 
public static string GetIsoStoreFileName(UIElement element) 
{ 
    return (string)element.GetValue(IsoStoreFileNameProperty); 
} 

// Using a DependencyProperty as the backing store for IsoStoreFileName. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty IsoStoreFileNameProperty = 
    DependencyProperty.RegisterAttached("IsoStoreFileName", typeof(string), typeof(IsoStoreImageSource), new PropertyMetadata("", Changed)); 

private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    Image img = d as Image; 

    if (img != null) 
    { 
     var path = e.NewValue as string; 
     SynchronizationContext uiThread = SynchronizationContext.Current; 

     Task.Factory.StartNew(() => 
     { 
      using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication()) 
      { 
       if (isoStore.FileExists(path)) 
       { 
        var stream = isoStore.OpenFile(path, System.IO.FileMode.Open, FileAccess.Read); 
        uiThread.Post(_ => 
        { 
         var _img = new BitmapImage(); 
         _img.SetSource(stream); 
         img.Source = _img; 
        }, null); 
       } 
      } 
     });    
    } 
} 

}

Tôi đang sử dụng này bên trong một điều khiển ListBox. Và nếu thử với hình ảnh thư viện mặc định, mọi thứ sẽ hoạt động như mong đợi. Nhưng nếu tôi thử với những hình ảnh có kích thước lớn (chụp qua camera của thiết bị) thì ứng dụng bị treo.

Và đây là ngoại lệ những gì tôi đang nhận được

Một ngoại lệ của loại 'System.OutOfMemoryException' xảy ra ở System.Windows.ni.dll nhưng không được xử lý theo mã người dùng

stack trace

tại MS.Internal.FrameworkCallbacks.NotifyManagedDebuggerOnNativeOOM() tại MS.Internal.XcpImports.BitmapSource_SetSource (BitmapSource bitmapSource, CValue & byteStream) tại System.Windows.Media.Imaging.BitmapSource.SetSourceInternal (stream suối ource) tại System.Windows.Media.Imaging.BitmapImage.SetSourceInternal (Stream streamSource) tại System.Windows.Media.Imaging.BitmapSource.SetSource (Stream streamSource) tại MyaPP.Common.IsoStoreImageSource. <> c__DisplayClass4. <> c__DisplayClass6.b__1 (Object _)

+0

Bạn có bao nhiêu hình ảnh trong chế độ xem danh sách của mình? Họ lớn đến mức nào?Bạn có thể chạy phân tích bộ nhớ trên ứng dụng của bạn ('Debug -> Bắt đầu phân tích ứng dụng Windows Phone -> Profiling -> Memory' trong Visual Studio) và đăng kết quả của bạn không? – Haspemulator

+0

Cố gắng sử dụng LongListSelector làm Danh sách Phẳng – Mahantesh

+2

@Haspemulator: Vấn đề được đề cập ở đây "http://stackoverflow.com/questions/15700340/out-of-memory-exception-while-loading-images-from-isolated-storage" , "http://blogs.developpeur.org/kookiz/archive/2013/02/17/wpdev-memory-leak-with-bitmapimage.aspx", Cách tôi có thể giải quyết vấn đề này với việc triển khai của bạn. –

Trả lời

0

Bộ nhớ đệm trong ListBox có thể chiếm bộ nhớ của bạn và điều này đặc biệt đáng chú ý với hình ảnh lớn hơn. Tôi không quen với phương thức trợ giúp bạn đã đăng nhưng hãy thử thêm.

if (img != null) 
{ 
    BitmapImage bitmapImage = img.Source as BitmapImage; 
    bitmapImage.UriSource = null; 
    img.Source = null; 

    //rest of the code ... 
} 
0

Được rồi, phải mất một chút thời gian để tôi quay lại vấn đề này. Tôi sẽ chia sẻ những phát hiện của tôi ở đây, nhưng tôi không xem xét chúng một câu trả lời thực sự cho vấn đề, mà là một giải pháp thay thế. Tuy nhiên, tôi hy vọng nó sẽ giúp ai đó.

Trước tiên, tôi muốn xác nhận OutOfMemoryException xảy ra trong một số trường hợp nhất định. Nhưng, đáng ngạc nhiên, nó phụ thuộc vào cách bố trí trang bạn đang sử dụng. Thực tế, nếu bố cục của bạn liên quan đến StackPanel, bạn sẽ có ngoại lệ. Tôi đoán, nó đi xuống đến thực tế như thế nào MeasureOverrideArrangeOverride phương pháp được thực hiện trong StackPanel (mặc dù tôi có thể hoàn toàn sai ở đây). Có vẻ như khi ListBox là một đứa trẻ đến StackPanel, nó sẽ cố gắng tải tất cả các hình ảnh trước khi hiển thị. Điều này, tất nhiên, gây ra rò rỉ bộ nhớ.

Mặt khác, nếu bạn sử dụng một cái gì đó như Grid làm cha mẹ cho danh sách hình ảnh, thì không có ngoại lệ như vậy và tải bộ nhớ là hợp lý.

Dưới đây là cách bố trí trang mà làm việc cho tôi:

<Grid> 
    <ListBox ItemsSource="{Binding IsoStorePics}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Image local:IsoStoreImageSource.IsoStoreFileName="{Binding Path}" Margin="5"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

Đây là câu trả lời tốt nhất mà tôi có cho bạn bây giờ. Xin vui lòng cho tôi biết nếu nó giúp.

+0

Tôi nghĩ rằng đó không phải là vấn đề. Tôi đã thử một cái gì đó như thế này,

+0

Và tôi cũng đã thử phương pháp trên mà bạn đã đề cập, nhưng kết quả thì giống nhau .. :( –

0

Bạn có thể thử như thế này, đối tượng Stream sẽ tự động được xử lý.

using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication()) 
{        
    if (iso.FileExists(imagePath)) 
    { 
     using (Stream imagestream = new IsolatedStorageFileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read, iso)) 
     { 
       BitmapImage bmp = new BitmapImage(); 
       bmp.SetSource(imagestream); 
       imgControl.Source = bmp; 
     } 
    } 
} 
Các vấn đề liên quan