2016-11-18 7 views
0

Der Versuch, eine asynchrone Client/Server-Anwendung in WinForms zu implementieren. Clientside-Code ist wie folgt:AsyncCallback wird nicht ausgelöst

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace AsyncClient 
{ 
    public partial class AsyncClient : Form 
    { 
     public AsyncClient() 
     { 
      InitializeComponent(); 
     } 

     //ManualResetEvent for notifying asyncronous threads that an event has occured 
     private static ManualResetEvent connectDone = new ManualResetEvent(false); 
     private static ManualResetEvent sendDone = new ManualResetEvent(false); 
     private static ManualResetEvent receiveDone = new ManualResetEvent(false); 

     //Response from the remote device (server) 
     private static String response = String.Empty; 

     //start client 
     private void button1_Click(object sender, EventArgs e) 
     { 
      TcpClient clientSocket = new TcpClient(); 
      try 
      { 
       var message = System.Text.Encoding.UTF8.GetBytes(txtFromClient.Text); //convert message to bytes for sending over the wire 
       using (clientSocket)/*(var clientSocket = new TcpClient("127.0.0.1", 1234)) *///make connection with the host 
       { 
        clientSocket.BeginConnect(IPAddress.Loopback, 1234, new AsyncCallback(connectCallBack), clientSocket); 
        sendDone.WaitOne(); 
        lblConnectionStatus.Text = "Connect is successfully established with the remote device."; 
        //send data to remote device 
        NetworkStream stream = clientSocket.GetStream(); //obtain network stream 
        stream.Write(message, 0, message.Length); //send data to the remote device 
        //sendDone.WaitOne(); 
       } 
      } 
      finally 
      { 
       clientSocket.Close(); 
      } 
     } 

     private static void connectCallBack(IAsyncResult ar) 
     { 
      try 
      { 
       var clientSocket = (TcpClient)ar.AsyncState; //retrieve socket from state object (IAsyncResult) 
       clientSocket.EndConnect(ar); //complete the connection 
       connectDone.Set(); 
      } 
      finally 
      { 

      } 
     } 

     private void txtFromClient_Click(object sender, EventArgs e) 
     { 
      txtFromClient.Text = ""; 
     } 
    } 
} 

Wenn ich button1 Text zu senden, UI ist das Einfrieren. Während dubug Modus fand ich, dass AsyncCallback(connectCallBack) in Zeile

clientSocket.BeginConnect(IPAddress.Loopback, 1234, new AsyncCallback(connectCallBack), clientSocket); 

nicht feuert und damit connectCallBack nicht ausgeführt wird. Programm ist eher halt auf Linie

sendDone.WaitOne(); 

Irgendwelche Ideen warum? Kann mir bitte jemand helfen?

+0

Check [dieser] (https://social.msdn.microsoft.com/ Foren/vstudio/de-DE/c359edfb-b6d9-4a21-bd82-ebbd2901d7e9/manualreseteventwaitone-hängt-meine-Anwendung? Forum = netfxbcl) – Kilazur

Antwort

2

Sie sind für sendDone.WaitOne(); und in Ihren Anruf wartet wieder verwenden Sie

connectDone.Set(); 

Sie sendDone.WaitOne(); mit connectDone.WaitOne();

+0

'connectDone.Set();' löste das Callback-Problem. UI friert auch nicht mehr. Der erste Sende vom Client wird erfolgreich auf dem Remote-Gerät empfangen. Problem ist mit dem Senden des zweiten Senders auf dem Client. "System.InvalidOperationException" in der Zeile "NetworkStream stream = clientSocket.GetStream();' meckern "Die Operation ist für nicht verbundene Sockets nicht erlaubt. ' – Jogi

2

Warum die UI friert ersetzen sollten: weil Sie auf dem Haupt zu verbinden versuchen, Thread, sodass die Benutzeroberfläche nicht mehr reagiert. Dies liegt daran, dass die Benutzeroberfläche im Hauptthread ausgeführt wird. Um dies zu lösen, versuchen Sie, sich mit einem anderen Thread als der Hauptbedrohung zu verbinden oder zu empfangen.

Warum der Rückruf nicht genannt wird: Sie sendDone.WaitOne(); mit connectDone.WaitOne(); ersetzen sollte, weil Sie connectDone.Set() einstellen und warten auf sendDone.WaitOne();

+0

'connectDone.Set();' löste das Rückrufproblem. UI friert auch nicht mehr. Der erste Sende vom Client wird erfolgreich auf dem Remote-Gerät empfangen. Problem ist mit dem Senden des zweiten Senders auf dem Client. "System.InvalidOperationException" in Zeile "NetworkStream stream = clientSocket.GetStream();' meckern "' Die Operation ist nicht auf nicht verbundenen Sockets erlaubt.' – Jogi

+0

Dies liegt daran, dass Ihr Socket geschlossen wurde oder die Verbindung im 'finally {clientSocket.Close(); } ' –