开发者

Mutex Usage question

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.CreateElem开发者_开发百科ent("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


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.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜