Monday, October 23, 2006

Something not to do in C# Part 2 My Code

Here is my C# code for this. I am no longer writing that the file opened in 0 minutes, and I am using built in tracing functionality. I am also loading more information from the config file than the application was previously. there is even more that could be moved, but I have let myself live with a few things.

using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Data;

namespace AfniRemovalArchive
{
class Removal
{

private const string ConfigFile = "Archive.xml";
private TraceSwitch deleteTrace = new TraceSwitch("deleteTrace", "Trace deleted file information");

[STAThread]
static void Main(string[] args)
{
Removal rmv = new Removal();
try
{
ArrayList localDepartments = rmv.GetConfigurationSettings();
rmv.CheckDepartments(localDepartments);
}
catch(Exception ex)
{
Trace.WriteLine( ex.ToString() );
}
}



private ArrayList GetConfigurationSettings()
{
ArrayList localDepartments;
Trace.WriteLine("Get configuration settings Begin: " + DateTime.Now.ToString());
string configpath = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location.ToString()), ConfigFile);
DataSet configds = new DataSet("config");
try
{
configds.ReadXml(configpath);
}
catch(System.Exception ex)
{
Trace.WriteLine("Get configuration settings: " + ex.ToString());
throw new Exception("Error reading configuration information", ex);
}
Trace.WriteLine("Configuration file loaded from: " + configpath );
localDepartments = new ArrayList();
// Create a list of Department configuration objects.
foreach(DataRow currentRow in configds.Tables["localdepartment"].Rows)
{
Department currentDepartment = CreateDepartment(currentRow);
localDepartments.Add(currentDepartment);
}
Trace.WriteLine( "Get configuration settings End: " + System.DateTime.Now.ToString() );
return localDepartments;
}
private Department CreateDepartment(DataRow currentDepartmentRow)
{
Department currentDepartment = new Department();
currentDepartment.departmentName = currentDepartmentRow["ldepartment"].ToString();
currentDepartment.localLocation = currentDepartmentRow["locallocation"].ToString();
currentDepartment.numberOfDays = Int32.Parse(currentDepartmentRow["numberofdays"].ToString());
return currentDepartment;
}
private void CheckDepartments(ArrayList localDepartments)
{
try
{
foreach(Department currentDepartment in localDepartments)
{
Trace.WriteLine("RemoveArchive for department " + currentDepartment.departmentName);
RemoveArchive(currentDepartment);
}
}
catch( Exception ex )
{
// something bad happened, log it, there is no recovery until we can see these errors.
Trace.WriteLine( "Error in CheckDepartments\n" + ex.ToString() );
}
}



private void RemoveArchive(Department currentLocalDepartment)
{
string[] archiveDirecotries = Directory.GetDirectories(currentLocalDepartment.localLocation);

DateTime cutOffDate = new DateTime(DateTime.Today.Ticks);
cutOffDate = cutOffDate.AddDays(-currentLocalDepartment.numberOfDays);
Trace.WriteLine("CutOffDate is " + cutOffDate);
int batchCount = 0;
for( int barcodeDir = 0; barcodeDir < archiveDirecotries.Length; barcodeDir++ )
{
string[] dirLocalBatch = Directory.GetDirectories(archiveDirecotries[barcodeDir], "*.ARCHIVE");
for( int batchDir = 0; batchDir<dirLocalBatch.Length; batchDir++ )
{
// check to see if i need to delete this directory.
DateTime createTime = Directory.GetCreationTime(dirLocalBatch[batchDir]);
if( createTime < cutOffDate )
{
Trace.WriteLineIf(deleteTrace.TraceError, "Deleting batch " + dirLocalBatch[batchDir] + " created at " + createTime );
Directory.Delete(dirLocalBatch[batchDir], true);
batchCount++;
}
else
{
Trace.WriteLineIf(deleteTrace.TraceVerbose, "Keeping batch " + dirLocalBatch[batchDir] + " created " + createTime );
}
}
}
Trace.WriteLine("Deleted " + batchCount + " batches.");
}

}

}

I'll also include my App.exe.config information. I leave a standard comment in my config files to make it easier for others to maintain later. I like to use Autoflush = true on the logging, this forces every write to actually write to the file. If you don't do this, you have to be particularly careful in your code to flush before ending due to an error, or you could lose the valuable tracing information that you need. I've never been comfortable with that, and always choose to set autoflush to true.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<system.diagnostics>

<!-- Note that all listeners are used all of the time. When logging
at an information level you may want to turn off email, or you will get overwhelmed. -->
<switches>
<!-- value = 0 = Logging off. -->
<!-- value = 1 = Log Errors. -->
<!-- value = 2 = Log Errors and Warnings. -->

<!-- value = 3 = Log Errors and Warnings and Information. -->
<!-- value = 4 = Log Errors and Warnings and Information and Verbose. -->
<!-- value > 4 is assumed to be 4. value < 0 is assumed to be 0 -->
<add name="deleteTrace" value="1" />
</switches>

<trace autoflush="true" indentsize="0">
<listeners>
<add name="TextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="\archiveTracing.txt" />
</listeners>
</trace>

</system.diagnostics>


</configuration>

No comments: