2013-07-23 4 views
0

Я задал вопрос здесь: The process cannot access the file because it is being used by another process: Correct way to read\write to a file: heavily used application-Part II.Прочтите напишите файл: сильно используемое приложение

У нас есть сильно используемое приложение .Net 3.5, которое читает «дорогие данные» и кэширует его. Однако мы получаем много ошибок, как при чтении файла кеша, так и при записи в файл кеша. У меня есть один процесс, несколько потоков, и я хочу, чтобы приложение синхронизировало доступ к ресурсу. Мне было рекомендовано использовать простой механизм блокировки, например lock или ReaderWriterLockSlim (см.: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx). Однако это, похоже, поставило проблему намного хуже в производстве.

EDIT После того, как изменение было реализовано, в конце концов многие файлы кеша имеют тег «>». Из-за этого файлы больше не являются файлами xml.

Может кто-нибудь посмотреть на код и сообщить, что я могу делать неправильно?

код до изменения:

private XmlDocument ReadFromFile() 
{ 
    XmlDocument result=null; 
    string fileSystemPath=FileSystemPath(); 
    try 
    { 
     result=new XmlDocument(); 
     using (StreamReader streamReader = new StreamReader(fileSystemPath)) 
     { 
      result.Load(streamReader); 
     } 
    } 
    catch (FileNotFoundException) 
    { 
     result=null; 
    } 
    return result; 
} 

private object thisObject= new object(); 
private void WriteToFile(string siteID, XmlDocument stuff) 
{ 
    string fileSystemPath=FileSystemPath(); 
    lock(thisObject) 
    { 
     using (StreamWriter streamWriter = new StreamWriter(fileSystemPath)) 
     { 
      stuff.Save(streamWriter); 
     } 
    } 
} 

код после изменения:

private readonly ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim(); 
private XmlDocument ReadFromFile() 
{ 
    XmlDocument result = null; 
    var fileSystemPath = FileSystemPath();   
    readerWriterLockSlim.EnterReadLock(); 
    try 
    { 
     result = new XmlDocument(); 
     using (var fileStream = new FileStream(fileSystemPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     using (var streamReader = new StreamReader(fileStream)) 
     { 
      result.Load(streamReader); 
     } 
    } 
    catch (FileNotFoundException) 
    { 
     result = null; 
    } 
    finally 
    { 
     readerWriterLockSlim.ExitReadLock(); 
    } 
    return result; 
} 


private void WriteToFile() 
{ 
    var fileSystemPath = FileSystemPath();    
    readerWriterLockSlim.EnterWriteLock(); 
    try 
    { 
     using (var fileStream = new FileStream(fileSystemPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)) 
     using (var streamWriter = new StreamWriter(fileStream)) 
     { 
      stuff.Save(streamWriter); 
     } 
    } 
    finally 
    { 
     readerWriterLockSlim.ExitWriteLock(); 
    } 
} 
+0

Лот ошибок не скажите нам, какие ошибки. Пожалуйста, будьте конкретны. – Ehsan

+0

Я отредактировал вопрос выше с разделом «EDIT» –

+0

Редактирование, которое вы упомянули, не имеет ничего общего с механизмом блокировки. Это означает, что кеш, который вы загружаете, недействителен. – Ehsan

ответ

0

Этот код с некоторыми небольшими изменениями должны работать

private readonly ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim(); 
private XmlDocument ReadFromFile() 
{ 
    XmlDocument result = null; 
    var fileSystemPath = FileSystemPath();   
    readerWriterLockSlim.EnterReadLock(); 
    try 
    { 
     result = new XmlDocument(); 
     using (var streamReader = new StreamReader(fileStream)) 
     { 
      result.Load(streamReader); 
     } 
    } 
    catch (FileNotFoundException) 
    { 
     result = null; 
    } 
    finally 
    { 
     readerWriterLockSlim.ExitReadLock(); 
    } 
    return result; 
} 


private void WriteToFile(XmlDocument stuff) 
{ 
    var fileSystemPath = FileSystemPath();    
    readerWriterLockSlim.EnterWriteLock(); 
    try 
    { 
     using (var streamWriter = new StreamWriter(fileSystemPath)) 
     { 
      stuff.Save(streamWriter); 
     } 
    } 
    finally 
    { 
     readerWriterLockSlim.ExitWriteLock(); 
    } 
} 
+0

И вы должны убедиться, что материал XmlDocument не изменен из другого потока, когда вы находитесь в методе WriteToFile –

+0

Это также предполагает, что контролируется только доступ к одному файлу. Или что нормально блокировать чтение файлов B, C, D, E и F при записи файла A. –

+0

@RossPresser, текущий код блокирует все записи/записи во все файлы при записи, гарантирует целостность всех файлов. Если вам нужен более продуктивный код, вы должны использовать блокировку чтения-записи файла. –

Смежные вопросы