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- 
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.