简体   繁体   中英

Why is the number objects in my WPF application increasing?

i write some code that reads a CSV file and convert it into a DateTable. In the next step it read the DataTable to get specific values. These values were saved in an object and this object will add to an ObserableCollection.

XAML:

<ListView ItemsSource="{Binding ProdOrderView}" x:Name="listView"    Margin="9,70,112,34" AlternationCount="2" FontSize="14">
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                    <Style.Triggers>
                        <Trigger Property="ItemsControl.AlternationIndex"  Value="0">
                            <Setter Property="Background" Value="White" />
                        </Trigger>
                        <Trigger Property="ItemsControl.AlternationIndex"  Value="1">
                            <Setter Property="Background" Value="LightGray" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View >
                <GridView >
                    <GridViewColumn  Header="Fauf" Width="Auto">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  Text="{Binding Fauf}" TextAlignment="Right" Name="fauf"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn  Header="Prod-Start" Width="Auto">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  Text="{Binding Start}" TextAlignment="Center" Name="start"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Rück- &#xa;stand" Width="Auto">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock x:Name="inRueck"  Text="{Binding InRueck}" TextAlignment="Center" />
                                <DataTemplate.Triggers>
                                    <DataTrigger Binding="{Binding InRueck, Converter={StaticResource ColorConverterInRueck}}" Value="delay">
                                        <Setter TargetName="inRueck" Property="Background" Value="Red" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding InRueck, Converter={StaticResource ColorConverterInRueck}}" Value="inTime">
                                        <Setter TargetName="inRueck" Property="Background" Value="Green" />
                                    </DataTrigger>
                                </DataTemplate.Triggers>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="heute" Width="Auto"  >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock x:Name="Heute" Text="{Binding Heute}" TextAlignment="Center" />
                                <DataTemplate.Triggers>
                                    <DataTrigger Binding="{Binding Heute}" Value="X">
                                        <Setter TargetName="Heute" Property="Background" Value="CornflowerBlue" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Heute}" Value="?">
                                        <Setter TargetName="Heute" Property="Foreground" Value="DarkViolet" />
                                    </DataTrigger>
                                </DataTemplate.Triggers>
                            </DataTemplate>

                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="morgen" Width="Auto" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  Text="{Binding Morgen}" TextAlignment="Center" Name="Morgen"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="+2" Width="Auto" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock  Text="{Binding Uebermorgen}" TextAlignment="Center" Name="Uebermorgen"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                ...

                </GridView>
            </ListView.View>
        </ListView> 

Code-behind:

 public MainWindow()
    {
        InitializeComponent();
        MainViewModel mvm = new MainViewModel(filepath,pline);
        listView.ItemSource = mvm.ProdOrderView;
    }

MainViewModel:

class MainViewModel
{
    #region Private Felder
    private ObservableCollection<ProductionOrder> _prodOrderList;

    private ListCollectionView _prodOrderView;
    #endregion

    #region Konstruktor
    public MainViewModel(string filepath, string pline)
    {
        // ProductionOrderliste initialisieren
        _prodOrderList = new ObservableCollection<ProductionOrder>();           

        _prodOrderList.Clear();
        fillObject(filepath, pline, ref _prodOrderList);

        // ListCollectionView initialisieren
        _prodOrderView = new ListCollectionView(_prodOrderList);

    }

    #endregion

    #region Öffentliche Eigenschaften
    public ListCollectionView ProdOrderView
    {
        get { return _prodOrderView; }
    }


    #endregion

    #region ConvertCSVtoDataTabble
    public DataTable ConvertCSVtoDataTable(string filename)
    {
        //DataTable anlegen
        DataTable dataTable = new DataTable();
        dataTable.Columns.Clear();
        dataTable.Rows.Clear();
        dataTable.Clear();

        try
        {
            //Filestream anlegen, dadurch kann Datei auch gelesen werden, wenn sie geöffnet ist
            FileStream logFileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            using (StreamReader streamReader = new StreamReader(logFileStream))
            {
                //Array mit allen Überschriften
                string[] headers = streamReader.ReadLine().Split(';');
                //Schleife durchläuft das Array headers
                foreach (string header in headers)
                {
                    //Der DataTable wird eine Spalte mit dem aktuellen header (Überschrift) hinzugefügt.
                    dataTable.Columns.Add(header);
                }
                //Schleife, die so lange gültig ist bis das Ende des Streams erreicht wurde
                while (!streamReader.EndOfStream)
                {
                    //Array mit allen Zeilen füllen
                    string[] rows = streamReader.ReadLine().Split(';');


                    //Der DataTable wird die Zeile mit dem aktuellen Werten der Zeile hinzugefügt.
                    dataTable.Rows.Add(rows);
                }
                //StreamReader wird geschlossen
                streamReader.Close();
                //Filestream wird geschlossen
                logFileStream.Close();
            }
        }
        catch(IndexOutOfRangeException e)
        {
            Console.WriteLine("Fehlercode:" + e);
            ConvertCSVtoDataTable(filename);
        }
            //gefüllte DataTable wird zurückgegeben
            return dataTable;

        }

    #endregion

    #region fillObbject
    public void fillObject(string filepath, string plinie, ref ObservableCollection<ProductionOrder> liste)
    {
        //DataTable res = new DataTable();
        //res.Columns.Clear();
        //res.Rows.Clear();
        //res.Clear();


        string emptyField = "\" \"";
        DataTable res = ConvertCSVtoDataTable(filepath);
        try
        {
            foreach (DataRow row in res.Rows) // Loop over the rows.
            {


                if (row["AFKO_PLTXT"].ToString() == plinie)
                {

                    ////Objekt anlegen
                    ProductionOrder order = new ProductionOrder();

                    //#region Prüft ob Sammelhinweis vorhanden
                    string sammel = "";
                    Queue<string> queue = new Queue<string>();

                    if (res.Columns.Contains("ZZTAG_MO"))
                    {
                        //Montag
                        if (row["ZZTAG_MO"].ToString() == "X")
                        {
                            sammel = "MO";
                            queue.Enqueue(sammel);
                        }
                        //Dienstag
                        if (row["ZZTAG_DI"].ToString() == "X")
                        {
                            sammel = "DI";
                            queue.Enqueue(sammel);
                        }
                        //Mittwoch
                        if (row["ZZTAG_MI"].ToString() == "X")
                        {
                            sammel = "MI";
                            queue.Enqueue(sammel);
                        }
                        //Donnerstag
                        if (row["ZZTAG_DO"].ToString() == "X")
                        {
                            sammel = "DO";
                            queue.Enqueue(sammel);
                        }
                        //Freitag
                        if (row["ZZTAG_FR"].ToString() == "X")
                        {
                            sammel = "FR";
                            queue.Enqueue(sammel);
                        }
                        //Samstag
                        if (row["ZZTAG_SA"].ToString() == "X")
                        {
                            sammel = "SA";
                            queue.Enqueue(sammel);
                        }
                        //Sonntag
                        if (row["ZZTAG_SO"].ToString() == "X")
                        {
                            sammel = "SO";
                            queue.Enqueue(sammel);
                        }


                    }
                    // string sammelList wird zusammengesetzt
                    string sammelList = "";
                    if (queue.Count > 0)
                    {
                        sammelList = "/";
                        while (queue.Count > 0)
                        {
                            if (queue.Count > 1)
                                sammelList += queue.Dequeue() + "+";
                            else
                            {
                                sammelList += queue.Dequeue();
                            }
                        }
                    }
                    #endregion
                    //das Objekt wird mit den entsprechenden Werten gefüllt
                    order.Fauf = row["EXTRA_APO"].ToString();
                    order.Start = row["GSTRP_KO"].ToString();
                    order.Vorgang = row["LTXA1_AFVC"].ToString();
                    order.Kundenauftrag = row["KDAUF_FK"].ToString() + sammelList;
                    order.Material = row["MATNR_PO"].ToString();
                    order.Materialbezeichnung = row["MAKTX_MAKT"].ToString();
                    order.Menge = row["AFKO_GAMNG"].ToString();
                    order.WE_Menge = row["WEMNG_PO"].ToString();
                    order.Ende = row["GLTRP_KO"].ToString();
                    order.Notiz = row["NOTIZ_TEXT"].ToString();
                    order.Ladedatum = row["LDDAT_VBEP"].ToString();
                    order.Dauer = row["FAUFDAUER_REST_KO"].ToString();

                    //führende Nullen werden entfernt falls vorhanden
                    order.Kundenauftrag = order.Kundenauftrag.TrimStart('0');
                    order.Material = order.Material.TrimStart('0');

                    if (order.Menge.Contains(","))
                    {
                        order.Menge = order.Menge.Remove(order.Menge.IndexOf(@","));
                    }
                    if (order.WE_Menge.Contains(","))
                    {
                        order.WE_Menge = order.WE_Menge.Remove(order.WE_Menge.IndexOf(@","));
                    }
                    order.Heute = "";
                    order.Morgen = "";
                    order.Uebermorgen = "";
                    order.Plus3 = "";
                    order.Plus4 = "";
                    order.Plus5 = "";

                    string inKlaerung = "";

                    //konvertiert String zu Datetime
                    DateTime newStartDate = convertDateTime(order.Start);
                    order.Start = newStartDate.ToString("dd.MM.yyyy");


                    //Berechne Verzug in Tagen
                    int verzugTage = (DateTime.Today - newStartDate).Days;
                    order.InRueck = verzugTage.ToString();

                    //konvertiert String zu Datetime
                    var newLadedatum = convertDateTime(order.Ladedatum);
                    order.Ladedatum = newLadedatum.ToString("dd.MM.yyyy");
                    if (inKlaerung != emptyField)
                    {
                        //X in der Spalte setzen, an dem Tag wo es gefertigt wird
                        if (verzugTage >= 0)
                        {
                            order.Heute = "X";
                        }
                        else
                        {
                            switch (verzugTage)
                            {
                                case -1:
                                    order.Morgen = "X";
                                    break;
                                case -2:
                                    order.Uebermorgen = "X";
                                    break;
                                case -3:
                                    order.Plus3 = "X";
                                    break;
                                case -4:
                                    order.Plus4 = "X";
                                    break;
                                case -5:
                                    order.Plus5 = "X";
                                    break;
                                default:
                                    break;
                            }

                        }
                    }
                    else
                    {
                        order.Heute = "?";
                    }
                    try
                    {
                        //konvertiert String zu Datetime
                        var newEndDate = convertDateTime(order.Ende);
                        order.Ende = newEndDate.ToString("dd.MM.yyyy");
                    }
                    catch (FormatException e)
                    {
                        Console.WriteLine("Fehlercode:" + e);
                        order.Ende = "Fehler";
                    }

                    // Prüft ob Vorgang leer ist 
                    if (order.Vorgang == emptyField)
                    {
                        order.Vorgang = "";
                    }

                    //Prüft ob Notiz leer ist
                    if (order.Notiz == emptyField)
                    {
                        order.Notiz = "";
                    }

                    //Prüft ob Dauer leer ist
                    if (order.Dauer == emptyField)
                    {
                        order.Dauer = "";
                    }


                    liste.Add(order);                                             
                }
            }               
        }

        catch (ArgumentException e)
        {

            Console.WriteLine("Fehlercode:" + e);
        }

    }
   // #endregion

    #region convertDateTime
    public DateTime convertDateTime(string date)
    {
        //konvertiert String zu Datetime
        DateTime newDate = DateTime.ParseExact(date,
                     "yyyyMMdd",
                      System.Globalization.CultureInfo.InvariantCulture);
        return newDate;

    }
    #endregion
}
}

When I load the CSV file every minute the amount of objects will increase extreamly. The Garbage Collector doesn't clear all old objects. can anybody help me to find this Problem?

my guess would be that your problem is that your using data tables where you don't need to.

A dataTable is a very complex item that is basically a code based database table and because of this is uses MarshalByValueComponent , which tells you that this can't be automatically GC'ed and as such requires you to call Dispose once you have finished using it. (calling Dispose tells it to clean up its links to unmanaged code and be available to the garbage collector).

you have 2 options for triggering disposal a simple call to the Dispose function or a Using(){} statement

you need to do this for all classes that are unmanaged (including StreamReader & FileStream)

as you aren't using the data table as a datatable, just a table then i would suggest removing it completely and just parsing your text file instead

EDIT:

Here as a quick and dirty model for a MVVM file parser

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:FileViewModel x:Name="vm" />
    </Window.DataContext>

    <DockPanel >
        <DockPanel DockPanel.Dock="Top">
            <Button DockPanel.Dock="Right" Click="Button_Click">Read</Button>
            <TextBox Text="{Binding File}" />
        </DockPanel>
        <ListView ItemsSource="{Binding ItemCollection}">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding field1}" Header="Feild1"/>
                    <GridViewColumn DisplayMemberBinding="{Binding field2}" Header="Field2"/>
                    <GridViewColumn DisplayMemberBinding="{Binding field3}" Header="Field3"/>
                    <GridViewColumn DisplayMemberBinding="{Binding field4}" Header="Field4"/>
                </GridView>
            </ListView.View>

        </ListView>
    </DockPanel>
</Window>

Code behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        vm.ReadFile();
    }
}

File Reader

public class FileViewModel : INotifyPropertyChanged
{
    private string _File;

    public string File
    {
        get { return _File; }
        set
        {
            _File = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("File"));
        }
    }

    public ObservableCollection<ItemModel> ItemCollection { get; } = new ObservableCollection<ItemModel>();

    public event PropertyChangedEventHandler PropertyChanged;

    public void ReadFile()
    {
        ItemCollection.Clear();

        using (StreamReader reader = new StreamReader(File))
        {
            var header =  reader.ReadLine();
            while(!reader.EndOfStream)
            {
                var data = reader.ReadLine();
                var item = ItemModel.Create(header, data, ',');
                ItemCollection.Add(item);
            }
        }
    }
}

Item Parser

public class ItemModel
{
    public static ItemModel Create(string colstr, string datastr, char delimiter)
    {
        var cols = colstr.Split(delimiter);
        var data = datastr.Split(delimiter);

        var item = new ItemModel();

        item.field1 = int.Parse(GetValue(cols, data, "field1"));
        item.field2 = DateTime.Parse(GetValue(cols, data, "field2"));
        item.field3 = GetValue(cols, data, "field3");
        item.field4 = double.Parse(GetValue(cols, data, "field4"));
        return item;
    }
    public static string GetValue(string[] cols, string[] data, string colName)
    {
        var colid = Array.IndexOf(cols, colName);
        if (colid == -1)
            return null;
        else
            return data[colid];
    }

    public int field1 { get; set; }
    public DateTime field2 { get; set; }
    public string field3 { get; set; }
    public double field4 { get; set; }

}

Demo File used

field2,field1,field4,field3
01-Jan-16,1,1.1,a
02-Jan-16,2,2.2,b
03-Jan-16,3,3.3,c
04-Jan-16,4,4.4,d

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM