You should not use file in a multi-threaded applications because the concurrency issues.
An example can be this content of a file:
Referrer: http://google.com
RefReferrer: http://stackoverflow.com
errer: http://meta.com
Referrer: http://yahoo.com
And this is pretty basic issue.
Instead, you can use file-based database (such as SQLite) or, of course, a proper database (not necessarily RDBMS).
Or in the worst case you have to synchronise the writes manually:
static class Stats {
static object locker = new object();
public static Write(string someData) {
lock(locker) {
using (var stream = File.Open("pathtofile", FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
using (var writer = new StreamWriter(stream)) {
writer.WriteLine(someData);
}
}
}
}
NOTE here:
- the synchronisation is handled within one and only one application (so you cannot generally have multiple processes working with the file;
- you don't need to check whether file exists or not.
FileMode.Append
will take care of that.
Another option would be to use Log4net that does handle the concurrency much better.
So that you can write your stats as log files:
static class Stats {
private static readonly ILog log = LogManager.GetLogger(typeof (Stats));
public static Write(string someData) {
log.Info(someData)
}
}