0

on my server i've got an xml file for each client which holds the packets which the client had not received. i need to access multiple client files on a server side. This happens from multiple background threads.

i'm looking for a way to create mutual Exclusion an a specific file. For example let's say iv'e got two clients john and tom and the method running in the background _AppendToUnsent

now lets say john has 2 packets to append and tom has 3. 2 threads would be dispatched for john and three for tom. i don't want to block a thread writing to tom.xml because a different thread is writing to john.xml

i would however want to block a second thread trying to access john.xml while a different one is already writing to the file

private static void _AppendToUnSent(object obj) { append_packets_mutex.WaitOne(); // this will block all threads no matter if the writing to the same file or not // holds the name and the packet KeyValuePair<String, byte[]> _pair = (KeyValuePair<String, byte[]>)obj; XmlDocument _doc = new XmlDocument(); // build the path of the file StringBuilder _builder = new StringBuilder(); _builder.Append(_path); _builder.Append(_pair.Key); _builder.Append(".xml"); if (!File.Exists(_builder.ToString())) { // if the file dosent exist create it XmlDeclaration xmlDeclaration = _doc.CreateXmlDeclaration("1.0", "utf-8", null); XmlElement rootNode = _doc.CreateElement(_pair.Value.ToString()); _doc.InsertBefore(xmlDeclaration, _doc.DocumentElement); _doc.AppendChild(rootNode); XmlElement _packets_node = _doc.CreateElement("Packets"); rootNode.AppendChild(_packets_node); _doc.Save(_builder.ToString()); } try { _doc.Load(_builder.ToString()); } catch (Exception es) { Console.WriteLine("Could Not save packet for " + _pair.Key); return; } // create and save a new <Packet> Node XmlNode declarition_node = _doc.FirstChild;// <Xml......> XmlNode packets_node = declarition_node.NextSibling;// <Messages> XmlElement _packet_node = _doc.CreateElement("Packet");// <Packet> _packet_node.InnerText = Convert.ToBase64String(_pair.Value);//43rg43g43yt42g.... // Encode to base64 _packet_node.AppendChild(_packet_node);// <Packet>43rg43g43yt42g....</Packet> try { _doc.Save(_builder.ToString()); } catch (Exception es) { Console.WriteLine("Could Not save packet from " + _pair.Key); } append_packets_mutex.ReleaseMutex(); // realese the genrel mutex for this operaition } // end _AppendToUnsente here 
2
  • 2
    I respectfully suggest you take some time to learn about how to accept answers and vote. So far on Stack Overflow you you seem to be taking but not giving. Commented Feb 20, 2011 at 20:07
  • the moment id have something to give ill do so, people here have helped me a lot ,and i appreciate it but i'm really new to programing and i'm afraid i might give out misleading answers in most cases, the topics here are mostly advanced so i'm kinda out of my league for now. Commented Feb 20, 2011 at 21:16

1 Answer 1

1

Your options:

  1. Since you are concerned with single thread access to a file on disk, you could open the file in exclusive read mode, which will prevent any other threads from opening the file until the file is closed.
  2. You could use named mutexes, and use the name of the file for the name of the mutex associated with the file.
Sign up to request clarification or add additional context in comments.

2 Comments

thanks, yeah i thought of using named mutexes but the first option hadn't occurd to me , with exclusive read mode block until the file could be opened or does it just throw an exception ?
The Win32 API call will fail with an error code. Stream classes or .NET wrappers will probably throw an exception. If you want a thread to wait until the file is available again, you'll probably need to set up a sleep/polling loop to try to open the file, if fail sleep for a little while, then loop and try again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.