2016-11-18 106 views
0

试图在WinForms中实现异步客户端/服务器应用程序。客户方代码如下:AsyncCallback未触发

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 = ""; 
     } 
    } 
} 

当我button1发送文本,UI被冻结。在dubug模式我发现,在一行AsyncCallback(connectCallBack)

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

不点火,因此没有被执行connectCallBack。程序停止在线

sendDone.WaitOne(); 

任何想法为什么?有人可以帮忙吗?

+0

检查[这](https://social.msdn.microsoft.com/论坛/ vstudio/en-US/c359edfb-b6d9-4a21-bd82-ebbd2901d7e9/manualreseteventwaitone-hangs-my-application?forum = netfxbcl) – Kilazur

回答

2

您正在等待sendDone.WaitOne();,并在您回电您使用

connectDone.Set(); 

你应该connectDone.WaitOne();

+0

'connectDone.Set();'确实解决了回调问题。用户界面也不再冻结。首先从客户端发送的消息在远程设备上成功接收。问题在于发送客户端上的第二次发送。在'NetworkStream stream = clientSocket.GetStream();'抱怨'上引发'System.InvalidOperationException'这个操作在未连接的套接字上是不允许的。 – Jogi

2

为什么UI被冻结更换sendDone.WaitOne();:因为您要在主连接线程使UI变得无法响应。这是因为UI在主线程上运行。为了解决这个问题,请尝试连接或接收与主要威胁不同的线索。

为何回调不叫:你应该更换sendDone.WaitOne();connectDone.WaitOne();因为你设置connectDone.Set(),你正在等待sendDone.WaitOne();

+0

'connectDone.Set();'确实解决了回调问题。用户界面也不再冻结。首先从客户端发送的消息在远程设备上成功接收。问题在于发送客户端上的第二次发送。在'NetworkStream stream = clientSocket.GetStream();'抱怨''''System.InvalidOperationException'上的操作不允许在未连接的套接字上。 – Jogi

+0

这是因为你的套接字已经关闭,或者连接在'finally {clientSocket.Close(); }' –