【发布时间】:2012-05-13 08:08:00
【问题描述】:
我有以下将客户端传递给 HandleStationClients 的客户端侦听器。 HandleStationClients 的构造函数在其他线程中启动一个带有连接的任务以进行侦听。
下面的代码使用异步函数在主线程上运行。当客户端连接时,下面的等待部分将继续并将客户端传递给新创建的 HandleStationClients 并挂钩事件。 通常在连接事件之后,循环将重新开始并在等待时等待新的连接。 问题是此代码为每个连接循环两次。因此客户端连接,HandleStationClients 将被创建,事件将被挂钩,while 循环再次开始,然后继续运行相同的进程,再次创建新的 HandleStationClients 和事件挂钩。
客户端处理完毕后,等待者不再等待而是继续第二次。事件被触发两次。我不知道怎么了。有人知道吗?
while (true)
{
counter += 1;
// Wait for new connection then do rest
stationsClientSocket = await stationsServerSocket.AcceptTcpClientAsync();
stationClients.Add(stationsClientSocket, 0);
Debug.WriteLine("Client toegevoegd " + counter);
HandleStationClients stationClient = new HandleStationClients(stationsClientSocket);
stationClient.ConnectionEstabilished += stationClient_ConnectionEstabilished;
stationClient.ConnectionClosed += stationClient_ConnectionClosed;
stationClient.NewDataReceived += stationClient_NewDataReceived;
}
HandleClient 看起来像
class HandleStationClients
{
public HandleStationClients(TcpClient client)
{
Task.Factory.StartNew(() => { ProcessConnection(client); });
}
#region Event definitions
public delegate void NewDataReceivedEventHandler(string newData);
public event NewDataReceivedEventHandler NewDataReceived;
public delegate void ConnectionClosedEventHandler();
public event ConnectionClosedEventHandler ConnectionClosed;
public delegate void ConnectionEstabilishedEventHandler(IPEndPoint endpoint);
public event ConnectionEstabilishedEventHandler ConnectionEstabilished;
#endregion
public async void ProcessConnection(TcpClient stationsClientSocket)
{
byte[] message = new byte[1024];
int bytesRead;
NetworkStream networkStream = stationsClientSocket.GetStream();
if (this.ConnectionEstabilished != null)
{
this.ConnectionEstabilished((IPEndPoint)stationsClientSocket.Client.RemoteEndPoint);
}
while ((true))
{
bytesRead = 0;
try
{
bytesRead = await networkStream.ReadAsync(message, 0, 1024);
}
catch (Exception ex)
{
// some error hapens here catch it
Debug.WriteLine(ex.Message);
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
ASCIIEncoding encoder = new ASCIIEncoding();
if (this.NewDataReceived != null)
{
byte[] buffer = null;
string incomingMessage = encoder.GetString(message, 0, bytesRead);
this.NewDataReceived(incomingMessage);
}
}
stationsClientSocket.Close();
// Fire the disconnect Event
this.ConnectionClosed();
}
}
【问题讨论】:
-
请展示一个简短但完整的程序来演示问题。仅凭这个 sn-p 就很难弄清楚发生了什么。
-
我同意乔恩的观点。我尝试运行一个简短的控制台应用程序,它运行良好。
-
我认为将(n 个整个)Task 设为异步方法并没有多大用处。
-
@Shift,那么你应该自己回答这个问题,或者删除它。
标签: c# wpf sockets async-await