2012-11-16 3 views
3

XML 파일을 사용하여 DB에있을 필요가없는 특정 데이터를 저장하는 응용 프로그램이 있습니다. 이 파일은 드물 긴하지만 동시에 페이지 사이에 쓸 수 있습니다. 이로 인해 문제가 발생하며 대부분 페이지 중 하나가 충돌하게됩니다. 다른 쪽이 파일에 쓰는 것이 완료 될 때까지 페이지 렌더링 대기를하는 방법이 있는지 궁금합니다.페이지 간 쓰기 용 잠금 (파일)?

모든 페이지 렌더링이 자체 스레드에서 실행된다고 가정 할 수 있는지 확실하지 않습니다. 그렇다면 lock() 명령과 같은 스레드를 중지하여 자원을 사용할 수있을 때까지 기다릴 수 있습니다. 그렇다면 어떻게 (메모리 세그먼트가 아닌) 파일에 lock()을 구현할 수 있습니까?

스레드가 없거나 lock()을 사용할 수없는 경우 파일을 쓸 수있는 다른 방법은 없지만 다른 사람이 파일을 사용하는 경우 파일을 사용할 수있을 때까지 기다릴 수 있습니까?

쓰기 순서와 권한을 관리하는 방법은 많이 있지만 간단합니다. 네가 두 번째로 온다면 다른 사람이 끝난 후에 글을 쓸 것이다. 필자는이 시점에서 쓰기 충돌에 대해서는별로 관심이 없지만 동시 쓰기는 해결해야 할 부분입니다.

도움을 주시면 대단히 감사하겠습니다.

+1

아직도는 DB에 저장해야합니다. 이것은 병행 성 문제를 해결할 것이고, 또한 문제가 생길 경우를 대비하여 원할하게 유지할 것이다. –

+0

데이터베이스를 사용하고 필요에 따라'optimistic' 또는'pessimistic' 동시성을 구현하는 것이 좋습니다. – RAS

+0

왜 무언가가 '추락 할'것이라고 생각합니까? 제발 좀 더 자세히 설명해주세요. 당신이 가지고 있지 않은 문제를 해결하지 마십시오. – avishayp

답변

1

는 단일 시스템에서라면, 당신이 사용할 수있는 Semaphorehttp://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx :

종류의 시스템 전체 잠금처럼
private static Semaphore _fileSemaphore = new Semaphore(1, 1, "myFileGlobalSemaphore"); 

// later... 

try 
{ 
    _fileSemaphore.WaitOne(); 
    // do stuff.. 
} 
finally 
{ 
    _fileSemaphore.Release(); 
} 

. 훌륭한 것은 아니지만 DB를 제안합니다. 또한 다른 것들은 파일 액세스가 실패 할 수도 있습니다. 적절한 잠금 모드를 사용하여 FileStream을 만드는 무언가를 구현할 수 있습니다. 두 소스에서 쓰기 위해 열려고 시도하지만 lock과 같은 시나리오는 수행하지 않습니다.

Btw : "DB에 저장할 필요가 없습니다". 당신이이 질문을하고 있다는 사실은 그것이 정말로 있어야 함을 시사합니다. 구현이 어려울 경우 데이터 액세스 전략을 다시 생각해 볼 수 있습니다. 엔티티 프레임 워크 (Entity Framework) (코드 첫 번째)와 같은 항목은 DB에서 물건을 "고정"하는 것을 매우 쉽게 만듭니다.

+0

정말 구현에 따라 다릅니다. 많은 것들은 음용 가능성과 관련이 있으며 짧은 앱 설정은 파일로 대신 보관 될 수 있습니다. 데이터베이스에 대한 적중 횟수를 줄이고 응용 프로그램을 다른 시스템에 복제해야하는 경우 포트를 적게 차지합니다. –

-2

일부 전역 잠금 개체를 사용하십시오. 예를 들어 당신의 global.asax.cs에 추가 페이지에서 다음

public static readonly object FileLock = new Object(); 

사용 :

lock(YourApplicationClass.FileLock) 
{ 
    // do stuff 
} 
+1

하나의 AppDomain (즉, 하나의 작업자 프로세스 만)이있는 경우에만 작동합니다. –

+0

또한 각 액세스가 자체 스레드에서 실행된다는 것을 보장 할 수 없습니다. 동일한 스레드에서 같은 개체를 잠그려고하면 화면이 멈추지 않을 것입니다. –

+0

그 의미는 ASPX 응용 프로그램 풀에 대해 익숙하지 않아서 실제로 각 페이지가 실행되는지 확인하는 것이 아닙니다. 자체 스레드. 나는 아무런 결과없이 인터넷 검색을 시도했다. –

2

편집 : (모노)에 좀 더 테스트를 실행, 난 그렇게 확실하지 않다 이것이 최선의 방법입니다.

아무 것도 충돌을 관리하지 못했지만 호출자에게 반환하기 전에 몇 초 동안 Run() 이후 실행이 일시 중지됩니다. 그래서 나는이 코드가 잘리는 징조가 아니라고 생각합니다.

즉, 테스트 된 시나리오는 사실과 거리가 멀다.


또 다른 옵션은 lockings 대한 OS 관리를 FileShare.ReadWrite 모드에서 파일을 열고 수 있도록하는 것입니다.

public void Run() 
    { 
     var file = @"/home/me/test.txt"; 
     var threads = new Thread[3]; 

     for (int i = 0; i < threads.Length; i++) { 
      int j = i; 
      threads[j] = new Thread(s => { 
      Console.WriteLine("thread " + j + " is running..."); 
      using (var stream = File.Open(file, FileMode.OpenOrCreate, 
        FileAccess.ReadWrite, FileShare.ReadWrite)) 
      { 
       Console.WriteLine("thread " + j + " is holding the file!"); 
       var data = ASCIIEncoding.ASCII.GetBytes("hello, I'm stream " + j); 
       stream.Write(data, 0, data.Length); 
       Thread.Sleep(1000); 
      }});  
     } 

     foreach (var t in threads) 
      t.Start(); 

     foreach (var t in threads) 
      t.Join(); 

     Console.WriteLine(File.ReadAllText(file)); 
    } 

출력 :

thread 1 is running... 
thread 0 is running... 
thread 2 is running... 
thread 2 is holding the file! 
thread 1 is holding the file! 
thread 0 is holding the file! 
hello, I'm stream 0