2011-05-04 1 views
2

목록이 있고 명명 된 파이프에서 해당 목록으로 데이터를 스트리밍한다고 가정 해 봅니다.해당 목록을 읽거나 사용할 수있는 동안 명명 된 파이프?

가상 샘플 : 그 목록을 예를 들어 모든 1000MS를 읽을 필요가 다른 스레드에서 다음

private void myStreamingThread() 
{ 
    while(mypipe.isconnected) 
    { 
     if (mypipe.hasdata) 
      myList.add(mypipe.data); 
    } 
} 

:

private void myListReadingThread() 
{ 
    while(isStarted) 
    { 
     if (myList.count > 0) 
     { 
      //do whatever I need to. 
     } 
     Thread.Sleep(1000); 
    } 
} 

여기 내 우선 순위 목록을 읽을 수있는 모든 1000 MS 목록에서 필요한 것은 무엇이든 할 수 있지만 동시에 파이프에서 나오는 새 데이터를 가져올 수있는 것이 매우 중요합니다.

좋은 방법은 무엇입니까?

은 내가 .NET 3.5

답변

1

나는 ConcurrentQueue을 사용하는 것이 좋습니다 것 (http://msdn.microsoft.com/en-us/library/dd267265.aspx)에 연결하고 언급하는 것을 잊었다. 간단한리스트 <을 사용하면 스레딩 문제가 많이 발생합니다.

또 다른 방법은 outstandingWork라는 뮤텍스를 사용하고 Thread.Sleep() 대신 대기하는 것입니다. 그런 다음 몇 가지 작업을 큐에 넣으면 뛰어난 작업을 수행합니다. 즉, 사용할 수있는 작업이 없을 때 잠을 자지 만 전체 1 초 동안 잠자기 대신 즉시 작업을 시작합니다.

편집

@Prix가 지적한 것처럼, 당신은 닷넷 3.5을 사용하고 있습니다. 그래서 당신은 ConcurrentQueue를 사용할 수 없습니다.

Queue<Work> queue; 
AutoResetEvent outstandingWork = new AutoResetEvent(false); 

void Enqueue(Work work) 
{ 
    lock (queue) 
    { 
     queue.Enqueue(work); 
     outstandingWork.Set(); 
    } 
} 

Work DequeMaybe() 
{ 
    lock (queue) 
    { 
     if (queue.Count == 0) return null; 
     return queue.Dequeue(); 
    } 
} 

void DoWork() 
{ 
    while (true) 
    { 
     Work work = DequeMaybe(); 
     if (work == null) 
     { 
      outstandingWork.WaitOne(); 
      continue; 
     } 
     // Do the work. 
    } 
} 
+0

@Richard는 정말 좋았지 만 .Net 4 – Prix

+0

감사합니다. @Prix, 내가 편집 할 것입니다. –

+0

뮤텍스를 사용하면 파이프가 새로운 데이터를 보낼 수 있기 때문에 어떤 시점에서 실패합니다. 한 번에 보내는 경우 파이프 라이팅에 실패하고 그 반대의 경우는 실패합니다. 그리고 답장을 보내 주셔서 감사합니다;) – Prix

2

자물쇠가 달린 Queue을 사용하는 것이 좋습니다. 대기열마다 1000 밀리 비우려면

Queue<string> myQueue = new Queue<string>(); 

private void myStreamingThread() 
{ 
    while(mypipe.isconnected) 
    { 
     if (mypipe.hasdata) 
     { 
      lock (myQueue) 
      { 
       myQueue.add(mypipe.data); 
      } 
     } 
    } 
} 

, Thread.Sleep를 사용하지 마십시오. 대신 timer을 사용하십시오.

System.Threading.Timer t = new Timer(myListReadingProc, null, 1000, 1000); 


private void myListReadingProc(object s) 
{ 
    while (myQueue.Count > 0) 
    { 
     lock (myQueue) 
     { 
      string item = myQueue.Dequeue(); 
      // do whatever 
     } 
    } 
} 

위의 내용은 큐가 하나의 스레드에서만 읽혀지고 있다고 가정합니다. 여러 스레드가 읽고 있다면 경쟁 조건이 있습니다. 그러나 위의 내용은 단일 독자와 한 명 이상의 작가와 함께 작동합니다.

+1

이것은 경쟁 조건이 있습니다. 자물쇠 밖의 백작을 테스트하고 있습니다. 그래서 count는 0보다 클 수 있습니다. 그러나 lock을 얻을 때 큐는 비어있을 수 있습니다! –

+0

@ 리차드 : 마지막에 댓글을 읽었을 때, 나는 그 경쟁 조건을 언급하고 독자가 하나라도 괜찮다고 언급했습니다. 다중 독자를 위해, 자물쇠 안에'조사'의 다른 체크를 간단하게 추가하십시오. –

+0

매우 감사, 그것은 단지 하나의 독자가 있기 때문에 잘 작동하는 것. – Prix