大量的图像吸收内存和内存异常?

时间:2017-11-20 16:59:16

标签: c# arrays json xamarin cross-platform

我遇到了日益增长的内存问题。有时几分钟后,应用程序因内存不足异常而崩溃。我从SQL服务器数据库中检索图像,并从单独的类中的字节转换。

我的XAML视图:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TestProject.Views.DetailViews.JsonDesertPage"
             xmlns:local ="clr-namespace:TestProject.Data">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:ByteArrayToImageConverter x:Key="severityTypeImageConvertertwo"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ListView x:Name="listviewConactstwo" RowHeight="100" HorizontalOptions="FillAndExpand" HasUnevenRows="True" ItemSelected="listviewContacts_ItemSelected">
        <ActivityIndicator x:Name="ProgressLoadertwo" IsRunning="True"/>
        <ListView.ItemTemplate >
            <DataTemplate>
                <ViewCell>
                    <StackLayout  Orientation="Vertical" Padding="5">
                        <StackLayout Orientation="Horizontal"  BackgroundColor="Ivory" Opacity="0.9">
                            <Image Source="{Binding Image,Converter={StaticResource severityTypeImageConvertertwo}}" HeightRequest="120" WidthRequest="120"/>
                            <StackLayout Orientation="Vertical">
                                <Label Text="{Binding Name}" FontSize="Medium" TextColor="Gray" FontAttributes="Bold"/>
                                <BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" HorizontalOptions="FillAndExpand" />
                                <Label Text="{Binding Description}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/>
                                <StackLayout Orientation="Horizontal" VerticalOptions="Start" HorizontalOptions="Start">
                                    <Label Text="$" FontSize="Micro" VerticalOptions="Start" HorizontalOptions="Start" TextColor="Gray" FontAttributes="Bold"/>
                                    <Label Text="{Binding Price}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/>
                                </StackLayout>
                            </StackLayout>
                            <Image Source="arrowtwo.png" BackgroundColor="Transparent" WidthRequest="25" Margin="0,10,10,0"/>
                        </StackLayout>                        
                    </StackLayout>                    
                </ViewCell>                
            </DataTemplate>            
        </ListView.ItemTemplate>        
    </ListView>
</ContentPage>

我的代码背后:

using Newtonsoft.Json;
using Plugin.Connectivity;
using System;
using System.IO;
using System.Net.Http;
using TestProject.Data;
using TestProject.Models;
using Xamarin.Forms;

namespace TestProject.Views.DetailViews
{
    public partial class JsonDesertPage : ContentPage
    {
        public JsonDesertPage ()
        {
            InitializeComponent ();   

            this.BackgroundImage = "background.png";
            this.Title = "Soup Menu";
            GetJSON();
          //  CrossConnectivity.Current.ConnectivityChanged += Current_ConnectivityChanged;
        }


        protected async override void OnAppearing()
        {
            base.OnAppearing();

            if (!CrossConnectivity.Current.IsConnected)
            {
                await DisplayAlert("fail", "No Internet Connection.Offline Menu Activated", "Ok");
                await Navigation.PushAsync(new MainTabbed());
            }
            else
            {
                // await DisplayAlert("sucess", " Network Is Available.", "Ok");
                GetJSON();
            }
        }

        public async void GetJSON()
        {                
            var client = new HttpClient();
            // var response = await client.GetAsync("http://192.168.43.226/GetContactsDesert.php");
            var response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php");    

            string contactsJson = response.Content.ReadAsStringAsync().Result;   
            ContectList ObjContactList = new ContectList();

            if (response.IsSuccessStatusCode)
            {                    
                ObjContactList = JsonConvert.DeserializeObject<ContectList>(contactsJson);
                listviewConactstwo.ItemsSource = ObjContactList.contacts;
            }

            else
            {
                var textReader = new JsonTextReader(new StringReader(contactsJson));
                dynamic responseJson = new JsonSerializer().Deserialize(textReader);
                contactsJson = "Deserialized JSON error message: " + responseJson.Message;
                await DisplayAlert("fail", "no Network Is Available.", "Ok");
            }

            ProgressLoadertwo.IsVisible = false;            

        }

        private void listviewContacts_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var itemSelectedData = e.SelectedItem as Contactone;
            Navigation.PushAsync(new JsonDetailsPage(itemSelectedData.ID, itemSelectedData.Image, itemSelectedData.Name, itemSelectedData.Code, itemSelectedData.Description, itemSelectedData.Price,itemSelectedData.isservicecharge, itemSelectedData.CostPrice));

        }
    }
}

这是我正在使用的页面之一:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace TestProject.Data
{
    public class ByteArrayToImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ImageSource retSource = null;
            if (value != null)
            {
                byte[] imageAsBytes = (byte[])value;
                // byte[] decodedByteArray = System.Convert.FromBase64String(Encoding.UTF8.GetString(imageAsBytes, 0, imageAsBytes.Length));
                // var stream = new MemoryStream(decodedByteArray);
                retSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
            }
            return retSource;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //return null;
            throw new NotImplementedException();
        }

    }
}

当我运行配置文件时,我可以看到,当我在页面之间移动时,再见[]正在成长。我尝试了FFimageloading选项,它似乎不支持字节数组图像转换器。

如何摆脱内存增长问题?

1 个答案:

答案 0 :(得分:0)

发现了一些事情。如果没有完整的运行,我无法确定哪些是你的头痛,但是......

使用HttpClient作为单身人士。我已经通过Xam arch证实,单例使用对于Xam以及其他所有内容都是最佳选择。

注意IDiposable对象。

以下代码返回HttpResponse方法。 HttpResponseMessage是IDisposeable。使用&#34;

将其包裹在&#34;中

StringReader继承自TextReader,它是IDisposable。使用&#34;包装&#34;

动态类型是不确定的。最好将它包装在一个使用中。有关详细信息,请参阅Do you need to dispose of objects and set them to null?

HttpClient的PNP指南 - https://github.com/mspnp/performance-optimization/blob/465514674354c8f833c73882f7405ac22c4fd437/ImproperInstantiation/docs/ImproperInstantiation.md

PNP好/坏HttpClient示例 - https://github.com/mspnp/performance-optimization/tree/465514674354c8f833c73882f7405ac22c4fd437/ImproperInstantiation

您正在使用HttpClient错误,这会破坏您的软件稳定性 - http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

看看这是否有帮助。

    private HttpClient m_httpClient = new HttpClient();
    private HttpClient MyHttpClient
    {
        get
        {
            if ( m_httpClient==null )
            {
                m_httpClient = new HttpClient();
            }
            return m_httpClient;
        }
    }
    public async void GetJSON()
    {
        // var client = new HttpClient();
        var client = MyHttpClient;

        // var response = await client.GetAsync("http://192.168.43.226/GetContactsDesert.php");
        // var response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php");
        string contactsJson = string.Empty;
        using (HttpResponseMessage response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php"))
        { 
            contactsJson = response.Content.ReadAsStringAsync().Result;
        }
        ContectList ObjContactList = new ContectList();

        if (response.IsSuccessStatusCode)
        {
            ObjContactList = JsonConvert.DeserializeObject<ContectList>(contactsJson);
            listviewConactstwo.ItemsSource = ObjContactList.contacts;
        }

        else
        {
            using (var textReader = new JsonTextReader(new StringReader(contactsJson)) )
            {
                using (dynamic responseJson = new JsonSerializer().Deserialize(textReader))
                { 
                    contactsJson = "Deserialized JSON error message: " + responseJson.Message;
                }
                await DisplayAlert("fail", "no Network Is Available.", "Ok");
            }
        }

        ProgressLoadertwo.IsVisible = false;
    }