using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace SudhirMurthy.Logger {
public interface ILog {
void LogToDisk(string msg);
}
interface ILoggerService {
ILog ILog {
get;
}
}
public class LogFile : ILog {
static List<string> messages;
//WriteToDisk delegate
private delegate void WriteToDisk(object sender, string fileName);
//WriteToDisk event
private static event WriteToDisk writeToDisk;
public static void WriteLog(string fileName) {
//Raise the event
writeToDisk(new object(), (fileName));
}
public void SendToDisk(object sender, string fileName) {
StreamWriter sw = File.CreateText(fileName);
foreach (string s in messages) {
sw.WriteLine(s);
}
sw.Close();
}
public LogFile() {
messages = new List<string>();
WriteToDisk mydelegate = new WriteToDisk(SendToDisk);
writeToDisk = new WriteToDisk(SendToDisk);
}
public List<string> Messages {
get {
return messages;
}
}
#region ILog Members
public void LogToDisk(string msg) {
Monitor.Enter(this);
messages.Add(msg);
Monitor.Exit(this);
}
#endregion
}
public class LoggerService : ILoggerService {
//TODO: Need to make it threadsafe..
private static ILog logInstance = null;
public LoggerService() {
logInstance = new LogFile();
}
#region ILoggerService Members
public ILog ILog {
get {
return logInstance;
}
}
#endregion
}
public class LoggerClient1 {
LoggerService logService;
public LoggerClient1() {
logService = new LoggerService();
}
public void Log() {
logService.ILog.LogToDisk(string.Format(
"I am Logging: {0}", this.ToString()));
}
}
public class LoggerClient2 {
LoggerService logService;
public LoggerClient2() {
logService = new LoggerService();
}
public void Log() {
logService.ILog.LogToDisk(string.Format(
"I am Logging: {0}", this.ToString()));
}
}
public class TestApp {
LoggerClient1 a;
LoggerClient2 b;
public TestApp() {
a = new LoggerClient1();
b = new LoggerClient2();
}
public void logClient1() {
for (int i = 0; i < 1000000; i++) {
a.Log();
}
}
public void logClient2() {
for (int i = 0; i < 1000000; i++) {
b.Log();
}
}
}
class Program {
static void Main(string[] args) {
TestApp app = new TestApp();
Thread t1 = new Thread(new ThreadStart(app.logClient1));
Thread t2 = new Thread(new ThreadStart(app.logClient2));
try {
t1.Start();
t2.Start();
} catch (Exception) {
throw;
}
t1.Join();
t2.Join();
//The main thread should technically wait until
//t1 and t2 should have finished and then execute
//the following
LogFile.WriteLog("log.txt");
}
}
}
If you try removing the Monitor.Enter(this) and Monitor.Exit(this) lines from the above code, you end up getting weird line numbers in your log.txt file. (enable line no's in visual studio and see log.txt). i.e the count of the log will never be as expected (2 million in the above case). By putting the above lines back, you get the expected value which is 2million lines of log. :). It takes about 5-6 seconds on my dual core for threads t1 and t2 to finish logging and the main thread to write to disk. :). A bloated 93.4 MB file!!
My thread on MSDN Forums.