2009-05-11 3 views
1

this 오픈 소스 라이브러리에 문제 해결에 어려움이 있습니다 ...이 라이브러리를 사용하면 응용 프로그램 설정을 저장하는 XML 파일을 쉽게 만들 수 있습니다. 하지만 변경 사항을 저장하는 데 문제가 있습니다.C#에서 XML 스트림을 저장하면 다른 프로세스에서 사용 중임을 알 수 있습니다.

나는이 라이브러리를 사용하는 다른 응용 프로그램을 가지고 있으며 응용 프로그램 창의 크기가 조정될 때마다 라이브러리의 Save() 메서드를 호출하여 창 크기/위치를 XML 파일에 저장합니다.

대부분의 경우 잘 작동하며 모든 것이 저장됩니다. 한번은 그래도 파일이 다른 프로세스에서 사용되고 있다고 말하는 예외가 있습니다.

정말 Save() 메서드가 호출 될 때마다 변경 사항이 저장되는지 확인해야합니다.이 예외를 어떻게 든 처리하거나 발생하지 않도록해야합니다.

이 상황을 가장 잘 처리하기위한 제안 사항은 무엇입니까?

public void Save() { 
    // Create a new XML file if there's no root element 
    if(xDocument.DocumentElement == null) { 
     xDocument = new XmlDocument(); 
     xDocument.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + 
      "<" + XmlRootElement + ">\n</" + XmlRootElement + ">"); 
    } 

    // OMITTED CODE WAS HERE (NOT IMPORTANT FOR THE PROBLEM) 

    // Create a new XML writer for the XML file 
    XmlWriter xWriter = XmlWriter.Create(XmlFilePath, new XmlWriterSettings() { 
     Indent = true, 
     IndentChars = "\t" 
    }); 

    // Sort the XML file using the XSL sylesheet and save it 
    xslTransform.Transform(xDocument, xWriter); 

    // Clear the buffer and close the XML writer stream 
    xWriter.Flush(); 
    xWriter.Close(); 
} 
+0

나는 lock 문을 넣는 답을 받아 들였고 멋지다는 것을 알았지 만 코드에서 using 문을 여전히 사용하도록주의 할 것입니다. 예상 한대로 자원을 항상 정리할 수 있습니다. 예외가있는 경우 파일을 올바르게 닫지 않고 잠금이 도움이되지 않기 때문에 파일에 경합이있을 수 있습니다. –

+0

나는 돌보아 주셔서 감사합니다. 그 질문에이 문제가 수정 되었기 때문에 그 대답을 받아 들였습니다.나는 더 이상 예외를 가지고 있지 않으며 다른 어떤 것도 갖지 못했습니다. (나는 미래에는 가지지 않을 것이라고 말하지 않습니다.) 그래서 문제는 해결되었습니다. 그래도, 당신의 추가 정보가 좋다. 그래서 내가 "도움이되는 대답"에 투표했다. :) –

답변

1

창 크기 조정 완료 이벤트가 너무 빨리 실행되고 저장 기능이 호출되고 첫 번째 실행이 완료되기 전에 다시 호출되는 경우 일 수 있습니다. 이렇게하면 설명하는 오류가 발생합니다 (파일을 사용하는 다른 프로세스는 ...!). Try surrounding your code with a lock, thusly는 :

lock(some_shared_object) 
{ 
    //Your code here 
} 
3

XmlWriter를이는 IDisposable입니다 :

저장() 메소드의 코드는 다음과 같다. using() 절에서이를 감싸 줘야합니다. http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx

+0

당신은 왜 lock() 대신에()를 사용해야하는지 거의 설명 할 수 있습니까? 지금까지, 나는 자물쇠에 대한 이유를 이해하고 나는 그것을 사용하기위한 것이 아니라 의미가 있다고 생각한다. ... –

+0

웁스; 나는 misspoken있을 수 있습니다. using() 절은 IDisposable을 구현하는 클래스에서 필수적입니다. 크기 조정 논리가 인터리브 또는 동시 크기 조정 이벤트를 허용하는지 여부에 따라 잠금이 필요할 수도 있습니다. – Cheeso

1

또한 lock 문을 사용해 볼 수도 있습니다. 이 방법들이 서로 오버런 할 수 있습니다.

+0

좀 더 구체적으로 말씀해 주시겠습니까? "lock 문"이 무엇인지 확실하지 않습니다 ... –

+0

using() 문이 99.44 %임을 확신합니다. 자물쇠가 필요하지 않습니다. – Cheeso

+0

XmlWriter.Close()에 대한 호출이 있기 때문에 using()이 루트 문제인지 확신 할 수 없습니다. 예외를 삼키는 catch 블록이 보이지 않기 때문에 예외가 발생하는 것을 보지 못합니다. Close()가 호출되지 않는 유일한 방법입니다. – GWLlosa

2

난 이미 여기에 주어진 답변의 조합으로 가야 해요.

XmlWriter는 여러 가지 이유로 사용 차단에 있어야합니다. 리소스를 최대한 빨리 해제 할 수 있도록 처리해야합니다. 또한, 당신이 그것과 상호 작용하는 동안 예외를 던지면 어떻게 될까? 파일이 제대로 닫히지 않을 것입니다. 적어도 finalizer가 시작되고 리소스가 해제 될 때까지는 말입니다.

using 문을 사용하더라도 파일에 경합이있을 수 있으며 잠금 코드에 저장 코드를 넣어야합니다. 이 파일은 공유 리소스이기 때문에 본질적으로 비진 출성입니다. 여러 개의 스레드가 없어도 잠금 기능을 사용하면 잠금을 해제 할 수 있지만 파일에 대한 액세스를 올바르게 제어 할 수 있습니다.

고려해야 할 다른 사항은 파일을 쓰려면 저장 작업을 백그라운드 스레드로 옮길 수 있습니다. 큰 설정 파일을 얻으면 사용자가 크기를 조정할 때마다 파일을 기다리고 있기 때문에 이상한 UI 상호 작용이 발생할 수 있습니다. 이는 UI 스레드에서 발생합니다. 이 작업을 수행했다면 반드시 파일 리소스에 대한 액세스를 잠글 필요가 있습니다.