2012-02-04 4 views
8

처음으로 명명 된 파이프를 사용하려고합니다.NamedPipeServerStream.EndWaitForConnection()을 사용하면 응답이 없습니다.

EndWaitForConnection이 BeginWaitForConnection에 대한 모든 호출에 대해 정확히 한 번만 호출해야합니다 : here를 발견 MS 문서에서는 상태.

그래서 나는 작은 프로그래머가되고 문서를 따르려고 노력하고 있지만, EndWaitForConnection()은 사용시 무기한으로 멈 춥니 다.

그래서 코드를 제거하고 문제를 격리 할 수 ​​있는지 확인하십시오.하지만 주사위는 없습니다. 필자가 작성한 클래스에서 다음 코드를 추출했습니다.

private void WaitForConnectionCallBack(IAsyncResult result) 
{ 

} 

public void Start() 
{ 
    var tempPipe = new NamedPipeServerStream("TempPipe", 
              PipeDirection.In, 
              254, 
              PipeTransmissionMode.Message, 
              PipeOptions.Asynchronous); 

    IAsyncResult result = tempPipe.BeginWaitForConnection(
            new AsyncCallback(WaitForConnectionCallBack), this); 

    tempPipe.EndWaitForConnection(result); // <----- Hangs on this line right here 
} 

1) EndWaitForConnection()에 끊지 않습니다 즉시 다음 파이프 연결을 대기 시작하는 파이프 연결에 대기 중지하려고 할 수 있도록 나는 그것을 수정 한? 연결을 받기 전에 서버를 종료하려면이 BeginWaitForConnection() 콜백을 어떻게 취소 할 수 있습니까?

2) 위에서 언급 한 문제가 없다고 가정 해 보겠습니다. 2 명의 클라이언트가 내 명명 된 파이프에 빠르게 연결하려고하면 어떻게됩니까?

각각에 대해 콜백 호출이 발생합니까? 아니면 첫 번째 연결 알림을 받기 위해 기다려야합니까? EndWaitForConnection() 다음 WaitForConnectionCallBack()을 다시 호출하여 다음 클라이언트 수신을 다시 시작합니다.

연결 동의자를 충분히 빠르게 설정할 수 없기 때문에 후자는 내게 경쟁 조건 인 것처럼 보입니다. 다음과 같이

+0

의도적으로 해당 호출은 콜백 메서드 (WaitForConnectionCallBack)에서만 사용해야합니다. tempPipe.Close()를 호출하여 취소 할 수 있습니다. –

+0

예, 저 자신의 결론에 일종의 일이 생겼습니다. 나는 기본적으로 tempPipe.Close()를 호출하면 콜백 루틴이 즉각적으로 움직인다는 것을 발견했다. 문제는 EndWaitForConnection을 즉시 호출하도록 설정했지만 파이프가 그때까지 닫혀 있기 때문에 예외가 발생하기 때문이다. 그래서 나는 try 문을 감싸고 catch 문에서 아무 것도하지 않아야했다. 이것이 올바른 해결책입니까? 파이프를 닫으려는 것은 다소 무리한 것 같아 콜백에서 예외를 강제로 잡아야한다는 것을 알게됩니다. – Ultratrunks

+0

그건 완전히 정상입니다. –

답변

8

그래서, 나를 위해 노력하고 솔루션의 기본 골격은 다음과 같습니다

여기
private void WaitForConnectionCallBack(IAsyncResult result) 
{ 
    try 
    { 
     PipeServer.EndWaitForConnection(result); 

     /// ... 
     /// Some arbitrary code 
     /// ... 
    } 
    catch 
    { 
     // If the pipe is closed before a client ever connects, 
     // EndWaitForConnection() will throw an exception. 

     // If we are in here that is probably the case so just return. 
     return; 
    } 
} 

는 서버 코드입니다.

public void Start() 
{ 
    var server= new NamedPipeServerStream("TempPipe", 
              PipeDirection.In, 
              254, 
              PipeTransmissionMode.Message, 
              PipeOptions.Asynchronous); 

    // If nothing ever connects, the callback will never be called. 
    server.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), this); 

    // ... arbitrary code 

// EndWaitForConnection() was not the right answer here, it would just wait indefinitely 
// if you called it. As Hans Passant mention, its meant to be used in the callback. 
// Which it now is. Instead, we are going to close the pipe. This will trigger 
// the callback to get called. 

// However, the EndWaitForConnection() that will excecute in the callback will fail 
// with an exception since the pipe is closed by time it gets invoked, 
// thus you must capture it with a try/catch 

    server.Close(); // <--- effectively closes our pipe and gets our 
         //  BeginWaitForConnection() moving, even though any future 
         //  operations on the pipe will fail. 
} 
+0

참고 읽기 전용 명명 된 파이프 (NamedPipeClientStream 클래스)에 대해 MessageMode를 사용할 때 [C# UnauthorizedAccessException] 참조 (http://stackoverflow.com/questions/32739224/c-sharp-unauthorizedaccessexception-when-enabling-messagemode-for-read-only -name)'Message' 모드 사용에 대한 다른 정보를 얻을 수 있습니다. – OmegaMan

관련 문제