2012-04-11 3 views
3

이번에는 초기 버전의 MSDN 예제를 기반으로하는 Async Socket Client와 관련된 또 다른 네트워킹 관련 질문입니다. 종점에 스위칭 네트워크 코드에있는 경우C# Async 소켓 클라이언트 블록 기본 인터페이스 스레드

//Mouse Event handler for main thread 
private void btn_Read_MouseDown(object sender, MouseEventArgs e) 
{ 
    Stopwatch sw = Stopwatch.StartNew(); 
    if (!networkDev.Connected) 
     networkDev.Connect("192.168.1.176", 1025); 

    if(networkDev.Connected) 
     networkDev.getReading(); 
    sw.Stop();//Time time taken... 
} 

- 사용자가 비동기 연결 시도가 네트워크 장치에 연결되어, 인터페이스의 버튼을 클릭하면 현재하면, 코드는 다음과 같습니다 잘 작동합니다 (전체 작동에 대해 1 초 미만). 그러나 네트워크 장치를 끄거나 사용할 수없는 경우 AsyncSocket Connect 함수는 기본 폼 스레드를 유지합니다. 현재 장치를 사용할 수없는 경우 전체 인터페이스가 약 20 초 동안 잠 깁니다 (스톱워치 사용). 주 스레드가 연결 요청에 대한 응답을 기다리고 있기 때문에 잠겨 있다고 생각합니다. 연결 요청을 다른 스레드에 넣어야한다는 의미입니까?

내가 코드를 내가 사용하고있는 비동기 소켓 클라이언트를 포함 한 -

public bool Connect(String ip_address, UInt16 port) 
    { 
     bool success = false; 

     try 
     { 
      IPAddress ip; 
      success = IPAddress.TryParse(ip_address, out ip); 
      if (success) 
       success = Connect(ip, port); 
     } 
     catch (Exception ex) 
     { 
      Console.Out.WriteLine(ex.Message); 
     } 
     return success; 
    }  

    public bool Connect(IPAddress ip_address, UInt16 port) 
    { 
     mSocket.BeginConnect(ip_address, port, 
      new AsyncCallback(ConnectCallback), mSocket); 
     connectDone.WaitOne();//Blocks until the connect operation completes, 
           //(time taken?) timeout? 
     return mSocket.Connected; 
    } 

    private void ConnectCallback(IAsyncResult ar) 
    { 
     //Retreive the socket from thestate object 
     try 
     { 
      Socket mSocket = (Socket)ar.AsyncState; 
      //Set signal for Connect done so that thread will come out of 
      //WaitOne state and continue 
      connectDone.Set(); 

     } 
     catch (Exception ex) 
     { 
      Console.Out.WriteLine(ex.Message); 
     }  
    } 
나는 그것의 자신의 스레드가 비동기 클라이언트를 사용하여이 다음 인터페이스 호스트 didn를이 경우 동결을 중지 할 것을 바라고 있었다

존재하지 않지만 이것이 사실 인 것처럼 보입니다. 초기 연결 실패 후 20 초가 지나면 모든 후속 연결 시도가 즉시 반환됩니다 (ms 미만). 또한 이상한 생각이 들었습니다. 초기 연결 시도가 성공하면 나중에 존재하지 않는 호스트에 연결하는 모든 호출이 즉시 반환됩니다. 무슨 일이 일어나고 있는지에 대해 다소 당혹 스럽지만, Socket이 사용하는 사실과 관련된 것이 AsyncSocket 클래스에 저장되어 있는지 궁금합니다. 클라이언트 코드가 더 필요하다면 어떤 도움을 주시면 감사하겠습니다.

+0

곳은 말한다 WaitOne 옆에있는 코멘트에서 "블록 작업이 완료 될 때까지?" 얼마나 비동기 적이며 어떤 스레드가 블록하다고 생각하십니까? – R0MANARMY

+0

나는 이제 이것을 꺼내 보았는데, 이것은 얼핏보기에 얼어 붙은 인터페이스에 관한 문제가 명백하게 드러났습니다. 이것은 초기 질문이었던 인터페이스 문제를 해결합니다. 그러나 Connect가 완료 할 수없는 경우 다시 사용할 수 없으며 비교적 자주 연결이 끊어 질 때 문제가 발생합니다. 각 AsyncClient는 1 소켓에 묶여 있습니다. 재 연결을 허용하는 가장 좋은 방법은 무엇입니까? 현재 스레드가 이전 연결 시작을 기다리고 있다는 예외가 발생합니다. 더 나은 해결책에 대한 제안은 감사하겠습니다. – jackocurly0074

답변

4

귀하는 비동기의 주장하지만 연결 방법은 명확하지 않습니다 :이 완료 될 때까지 당신은 비동기 행동의 정반대 인 차단하고

mSocket.BeginConnect(ip_address, port, ...); 
connectDone.WaitOne(); // Blocks until the connect operation completes [...] 

. 연결될 때까지 차단하려는 경우 BeginConnect을 사용하는 이유는 무엇입니까?

+0

흠 나는 MSDN 예제를 사용하여 코드를 기반으로하므로 WaitOne을 연결에 넣는 이유를 이해할 수 없습니까? 예제 (http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx)가 훌륭한 시작점 이었으면 좋겠다. 나는 틀렸어! 잠시 기다리지 않고 버튼을 몇 번 누르면 다른 작업이 진행되는 동안 연결할 수 없다는 많은 예외가 발생합니다. 어쨌든 다른 연결 시도를 시간 초과하면 불안정한 환경에서 재 연결 시도가 더 자주 이루어질 수 있습니까? – jackocurly0074

+1

@ jackocurly0074 : 연결 시간 제한 등록 정보를 볼 수 없습니다. * 아니요.하지만 여러 개의 동시 연결을 시도하지 않는 것이 좋습니다. –

1

당신은 여기 UI 스레드를 차단하고 있습니다 :

당신이 볼
connectDone.WaitOne(); //Blocks until the connect operation completes, (time taken?) timeout? 
+0

너희들은 매우 빨리 답장을 보내고있다. WaitOne을 실행하면 인터페이스가 멈추지 만 다른 문제가 발생합니다.- System.dll에서 'System.InvalidOperationException'유형의 첫 번째 예외가 발생했습니다. 동일한 소켓에서 다른 비동기 작업이 진행되는 동안 BeginConnect를 호출 할 수 없습니다. 문제는 소켓을 연결하지 못하면 다시 사용할 수없고 나머지 런타임에서는 사용할 수없는 것으로 보입니다. – jackocurly0074