2012-04-26 5 views
0

서비스가 실행되는 동안 생성 된 XML 목록을 저장하려는 WCF 서비스가 있습니다 (서비스를 닫으면 다시 보게됩니다). 서비스 재시작. 항목은 HTTP POST가 호출 될 때 목록에 추가됩니다. 그러나 목록의 항목을 반환하는 프로그램의 HTTP GET 메서드가 서비스를 다시 시작한 후에 호출되면 목록의 항목이 저장되지 않으므로 목록의 항목이 표시되지 않습니다. 이 문제와 관련된 제 질문은 다음과 같습니다.WCF 서비스에서 만든 목록을 저장하여 서비스가 다시 시작될 때 확인합니다.

1) 나중에 참조 할 수 있도록 어떻게 목록을 저장할 수 있습니까? 2) 서비스가 다시 시작될 때마다이 목록을 저장할 수있는 메커니즘이 있습니까?

포인터가 하나만 더 : 로컬 컴퓨터에 목록 항목을 xml 파일로 저장하지 않겠습니다.

+0

사용자 지정 서비스 호스트를 구현하고 호스트의 OnClosing 이벤트에서 서버의 파일에 목록을 저장하는 방법을 살펴보십시오. 또는 데이터베이스에 저장할 수도 있습니다. 그런 다음 호스트의 OnOpening에서 db의 파일이나 데이터를 읽을 수 있습니다. – Tim

답변

1

Tim의 제안은 적당하지만 사용자 지정 서비스 호스트가 필요하지 않습니다. 가장 중요한 점은 데이터가 업데이트 된 후 어느 시점에서 영구 저장소에 데이터 내용을 쓰는 것입니다. POST를 받으면 메모리 내 데이터 표현을 업데이트 한 다음 파일 시스템의 XML 파일에 내용을 씁니다.

public void DoPost() 
    { 
     UpdateData(); 
     SaveDataToFilesystem(); 
    } 

다시 시작할 때 파일이 있으면이를 읽습니다.

동시성을 처리하려면 Update()Save() 메서드에서 데이터를 잠글 수밖에 없습니다.

시스템에 부하가 많은 경우 "파일 시스템에 쓰기"를 최대 10 초마다 연기하십시오.

public void DoPost() 
    { 
     UpdateData(); 
     QueueWriteToFilesystem(); 
    } 

    private MyInternalDataType data; 
    private DateTime lastWrite = new DateTime(1970,1,1); // init value 
    private void QueueWriteToFilesystem() 
    { 
     ThreadPool.QueueUserWorkItem(MaybeWrite); 
    } 


    private int delayInMilliseconds = 1000 * 10; // 10 seconds 
    private void MaybeWrite() 
    { 
     System.Threading.Thread.Sleep(delayInMilliseconds); 
     lock (data) 
     { 
      var delta = System.DateTime.Now - lastWrite; 
      if (delta < new System.TimeSpan(0, 0, 0, 0, delayInMilliseconds)) 
      { 
       // less than 10s since last write 
       // do nothing 
       return; 
      } 
      ActuallySaveToFilesystem(); 
      lastWrite = System.DateTime.Now; 
     } 
    } 

정말 높은 동시성를 들어, 모든 요청과 새로운 작업 항목을 대기 싶지 않을 것이다. 대신에 쓰기 전용 스레드를 사용하는 것이 좋습니다.

public void DoPost() 
    { 
     UpdateData(); 
     lastUpdate = System.DateTime.Now; 
    } 

    private void DedicatedWriter() 
    { 
     do 
     { 
      System.Threading.Thread.Sleep(delayInMilliseconds); 
      lock (data) 
      { 
       var delta = lastUpdate - lastWrite; 
       if (delta < new System.TimeSpan(0, 0, 0, 0, 200)) 
       { 
        // small amount of time since prior write; 
        // do nothing 
        return; 
       } 
       ActuallySaveToFilesystem(); 
       lastWrite = System.DateTime.Now; 
      } 
     } while (true); 
    } 

또한 AutoResetEvents를 사용하여 작성자 스레드가 깨우기 위해 신호를 보낼 수 있습니다.

관련 문제