|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionWhen interfacing to real-world devices, it is typical to have one or more background processing tasks responsible for collecting data and/or controlling the devices. Monitoring these tasks can be done in a variety of ways, some of which can involve complex GUI components for status reporting and user interaction for control. As the name implies, the There are many logging frameworks and APIs available, along with tools to deal with the Windows Event Log. I counted no less than 30 related CodeProject articles. While you could possibly use some of these tools, their functionality is not generally applicable to the requirements described below. That said, I should note that the project This article also details how I used some basic .NET 2.0 Framework capabilities in the solution. There are no tricks or undocumented system features here. You can think of this as a C# 2 beginner's tutorial that shows some of the language features that would be useful in your day-to-day development work. RequirementsThe development of the
The specific requirements are:
LogString Class
Static Methodsstatic LogString GetLogString(string name); // Get a LogString instance
static void PersistAll(); // Save all LogString instances
static void ClearAll(); // Clear the contents of all LogString instances
static void RemoveLogString(string name); // Remove the named LogString instance
Instance Methodsvoid Add(string message); // Add a message
void Persist(); // Save this LogString instance
void Clear(); // Clear this LogString instance
Instance Propertiesstring Log; // This is the log string
delegate void LogUpdateDelegate(); // The notification delegate
event LogUpdateDelegate OnLogUpdate; // The update event
Option properties: See table.
The LogString myLogger = LogString.GetLogString("Task1");
The returned object is a myLogger.Add("Something important happened!");
A monitoring task accesses the entire contents of the log though the textBox1.Text = myLogger.Log
Automatic updates to a viewer are achieved by adding a myLogger.OnLogUpdate += new LogString.LogUpdateDelegate(this.LogUpdate);
The Each log LogString.PersistAll();
An individual log can be cleared with the The Multiple SingletonsA private static Hashtable m_LogsTable = new Hashtable();
public static LogString GetLogString(string name)
{
// If it exists, return the existing log.
if (m_LogsTable.ContainsKey(name)) return (LogString)m_LogsTable[name];
// Create and return a new log.
LogString rv = new LogString(name);
m_LogsTable.Add(name, rv); // add to table
return rv;
}
// Constructor
private LogString(string name)
{
m_strName = name;
ReadLog(); // Read existing
}
Each Notice that the Access LockingIn order to provide thread safe operation, whenever the internal log public void Clear()
{
lock (m_strLog) // lock resource
{
m_strLog = string.Empty;
}
WriteLog(); // This will remove the log file
// Notify listeners of the update
if (OnLogUpdate != null) OnLogUpdate();
}
When one thread is inside the lock code block, another thread that executes a lock on the same object will be blocked until the other thread exits their block. I have used the C#
Event GenerationA public delegate void LogUpdateDelegate();
public event LogUpdateDelegate OnLogUpdate;
When a change to the if (OnLogUpdate != null) OnLogUpdate();
A client would use the following to update a private System.Windows.Forms.TextBox txtLog;
...
myLogger.OnLogUpdate += new LogString.LogUpdateDelegate(this.LogUpdate);
...
private delegate void UpdateDelegate();
private void LogUpdate()
{
Invoke(new UpdateDelegate(
delegate
{
txtLog.Text = myLogger.Log;
})
);
}
The ConclusionIf you have requirements that are close to what I've outlined, then you can use the History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||