tags:

views:

25

answers:

3

Hello,

I have created a web application which is creating and updating the xml file on daily basis. i.e. Creating a xml as currentdate.xml. This have all the records of user's visited i.e IP, refferer, visited page and some more.

So the same file updating from multiple users at same time. So what are the best practice to check the file existence & updating.

I am getting the "File is in use by another process"

Thanks, Laxmilal

+1  A: 

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)
  }
}
Dmytrii Nagirniak
+1  A: 

I agree with Toms reaction: If you can, please use a database. It is designed for multi-threaded access. If this is not possible for whatever reason, try writing no different files to prevent asynchronous exceptions. Otherwise you can try taking a lock, like this:

private static readonly object locker = new object();

public static void MyMethodThatWritesToFile()
{
    lock(locker)
    {
        // Do file IO here.
    }
}

Note that this will only work within a single AppDomain. When you have multiple applications writing to the same file, you need a process wide lock.

Perhaps you can use a logging framework such as CuttingEdge.Logging (for instance the XmlFileLoggingProvider). They are designed to handle thread-safety for you.

Steven
A: 

Thanks, Now no error after using Lock / SharedLock in my web application.

Please, mind to accept the answer. Also StackOverflow is not a forum, if you want to reply to somebody's answer, you need to add comment but not another answer for your own question. Cheers.
Dmytrii Nagirniak