2012-04-11 131 views
3

這次的另一個網絡問題涉及基於MSDN示例的異步套接字客戶端,至少在此初始版本中。目前,當用戶點擊一個異步連接嘗試連接到網絡設備的接口上的按鈕,該代碼如下所示 -C#異步套接字客戶端塊主接口線程

//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... 
} 

如果終點被接通並且存在於網絡的代碼上工作正常(整個操作少於一秒)。但是,如果聯網設備關閉或不可用,則AsyncSocket Connect功能會佔據主窗體線程。目前,如果設備不可用,則整個界面鎖定約20秒(使用秒錶)。我認爲我正在鎖定,因爲主線程正在等待Connect請求的返回,這是否意味着我需要將該連接請求放在另一個線程上?

我已經包含的代碼我使用的異步套接字客戶端 -

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); 
     }  
    } 

我希望通過它有自己的線程中的異步客戶端,這將然後停止凍結如果主機沒界面不存在,但似乎並非如此。初始連接失敗後需要20秒,所有後續連接嘗試立即返回(小於一個毫秒)。還有一件我覺得奇怪的事情,如果初始連接嘗試成功,任何稍後調用連接到一個不存在的主機立即返回。對發生了什麼感到困惑,但是想知道它是否與我使用的Socket存儲在我的AsyncSocket類中有關。任何幫助非常感謝,如果更多的客戶端代碼需要讓我知道。

+0

你看到在旁邊WaitOne的評論,它說「阻塞,直到操作完成」?這個異步程序到底是什麼,你認爲它阻塞了哪個線程。 – R0MANARMY 2012-04-11 09:53:16

+0

我現在把這件事看出來了,因爲事後看來,這種凍結界面的問題非常明顯。這解決了接口問題,這是最初的問題,儘管看起來如果Connect無法完成,我不能再次使用該套接字,並且這在連接可能相對頻繁地發生時是個問題。每個AsyncClient綁定到1個套接字,最好的方式是什麼允許重新連接?目前我只是收到異常,表示線程正在等待先前的開始連接。有關更好的解決方案的任何建議,我們感激。 – jackocurly0074 2012-04-11 10:22:18

回答

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 2012-04-11 09:55:29

+1

@ jackocurly0074:我看不到任何連接超時屬性,但是你應該確保你不嘗試創建多個併發連接。 – 2012-04-11 10:02:51

1

你在這裏擋住你的UI線程:

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

你們回覆得非常快,謝謝!取出WaitOne會阻止界面凍結,但會產生另一個問題。這發生在隨後的連接嘗試 - > System.dll中發生類型'System.InvalidOperationException'的第一次機會異常 在同一套接口上正在進行另一個異步操作時,無法調用BeginConnect。 問題是,一旦套接字連接失敗,我不能再次使用它,它似乎是其他運行有問題的不可用的? – jackocurly0074 2012-04-11 10:03:24