Adding events to LINQtoCSV library
The User Experience that a library provides must be at least equal with is quality and speed. And frankly, CSVtoLINQ rocks on latest two, as I presented in previous articles Import CSV file and query it with LINQ and continuing in LINQ wonder world, but lacks a little on the User Experience(in our case Developer Experience) by not having some events of starting, progress and ending of the parsing.
Especially important, while parsing huge files, is a confirmation for the user that something happens and (ideally) the point in which the processing is. That is why, thanks to Matt Perdeck for sharing the entire source of the library, I was able to improve it by adding events.
So, let’s see some code!
Modifications into LINQtoCSV library – CSVContext.cs
Important: All modifications will be made in the CsvContext class from LINQtoCSV namespace – the CSVContext.cs file.
First we’ll add the ReadStarted event to the library – it will fire when the reading of the CSV file has started.
// defining the delegate
public delegate void ReadStartedHandler(object sender, EventArgs e);
// here we define the event
public event ReadStartedHandler ReadStarted;
// the call of the event processing
protected virtual void OnReadStarted() {
if (ReadStarted != null) {
// we use empty eventargs because nothing is needed on readstarted event, just the confirmation of parsing started
ReadStarted(this, EventArgs.Empty);
}
}
Similarly, we define the complete event:
public delegate void ReadCompletedHandler(object sender, EventArgs e);
public event ReadCompletedHandler ReadCompleted;
protected virtual void OnReadCompleted() {
if (ReadCompleted != null) {
ReadCompleted(this, EventArgs.Empty);
}
}
For the progress we have to do a small addition by creating our own EventArgs type:
public class ProgressArgs : EventArgs {
private int _Progress;
private int _Max;
public int MaxValue {
set {
_Max= value;
}
get {
return this._Max;
}
}
public int Progress {
set {
_Progress = value;
}
get {
return this._Progress;
}
}
}
public delegate void ReadProgressHandler(object sender, ProgressArgs p);
public event ReadProgressHandler ReadProgress;
protected virtual void OnReadProgress(ProgressArgs p) {
if (ReadProgress != null) {
ReadProgress(this, p);
}
}
As the events and event arguments were created, we have to insert their calls into the code, with specific line numbers (might differ a little at your implementation time, but that’s why I presented some of the surrounding code) from the CSVContext.cs:
(...)
#region Get line counting for progress
int count = 0;
string line;
while ((line = stream.ReadLine()) != null) {
count++;
}
ProgressArgs p = new ProgressArgs();
p.MaxValue = count;
#endregion
(...)
(...)
AggregatedException ae =
new AggregatedException(typeof(T).ToString(), fileName, fileDescription.MaximumNbrExceptions);
try {
ReadStarted(this, EventArgs.Empty);
bool firstRow = true;
while (cs.ReadRow(ref row)) {
p.Progress++;
ReadProgress(this, p);
(...)
And of course, the ReadCompleted event:
(...)
finally {
if (readingFile) {
stream.Close();
}
ReadCompleted(this, EventArgs.Empty);
(...)
Modifications in your application
Now, in your application you have to register and create methods responding to the events:
CsvContext cc = new CsvContext(); // add event handlers cc.ReadStarted += new CsvContext.ReadStartedHandler(cc_ReadStarted); cc.ReadCompleted += new CsvContext.ReadCompletedHandler(cc_ReadCompleted); cc.ReadProgress += new CsvContext.ReadProgressHandler(cc_ReadProgress);
While the ReadStarted and ReadCompleted events are trivial, I feel that ReadProgress deserves to be presented as code( here tsProgressBar is a System.Windows.Forms.ToolStripProgressBar):
void cc_ReadProgress(object sender, ProgressArgs e) {
if (tsProgressBar.Maximum != e.MaxValue)
tsProgressBar.Maximum = e.MaxValue;
tsProgressBar.Value = e.Progress;
this.Cursor = Cursors.Default;
}
That’s all folks – Enjoy the code!
| Print article | This entry was posted by Radu Poenaru on 6 February 2010 at 1:40 pm, and is filed under 2009 - Fraunhofer FIT, My work. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |




