Mutex Вопрос об использовании - PullRequest
0 голосов
/ 20 февраля 2011

на моем сервере у меня есть xml-файл для каждого клиента, который содержит пакеты, которые клиент не получил. Мне нужно получить доступ к нескольким файлам клиента на стороне сервера. Это происходит из нескольких фоновых потоков.

Я ищу способ создать взаимное исключение определенного файла. Например, скажем, у меня есть два клиента Джон и Том, а метод работает в фоновом режиме _AppendToUnsent

теперь допустим, что Джону нужно добавить 2 пакета, а Тому - 3. 2 потока будут отправлены для Джона и три - для Тома. я не хочу блокировать запись потока в tom.xml, потому что другой поток пишет в john.xml

однако я хотел бы заблокировать второй поток, пытающийся получить доступ к john.xml, в то время как другой файл уже записывает в файл

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

1 Ответ

1 голос
/ 20 февраля 2011

Ваши варианты:

  1. Поскольку вас беспокоит однопотоковый доступ к файлу на диске, вы можете открыть файл в монопольном режиме чтения, что не позволит другим потокам открывать файл до тех пор, пока файл не будет закрыт.
  2. Вы можете использовать именованные мьютексы и использовать имя файла для имени мьютекса, связанного с файлом.
...