C #: Bater em ManualResetEvent
-
03-07-2019 - |
Pergunta
Eu escrevi meu código usando este artigo no MSDN como um ajudante primária
Meu código:
private ManualResetEvent _AllDone = new ManualResetEvent(false);
internal void Initialize(int port,string IP)
{
IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Accpt.Bind(_Point);
_Accpt.Listen(2);
while (true)
{
_AllDone.Reset();
_Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
_AllDone.WaitOne(); <<crash here
}
}
Isto é o que acontece, eu definir um ponto de interrupção na BeginAccept (Eu pensei que não é o problema), mas os passos que normally.However, quando tento passo "_AllDone.WaitOne ()." - a queda do servidor
Se _allDone não pode ser usado em um aplicativo de formulário win32 - como eu faço o meu projeto
Editar
Eu esqueci de mencionar que eu escrevi _AllDone.Reset () em Accept (), mas não ir para lá, eu definir um ponto de interrupção lá, mas ele não vai.
private void Accept(IAsyncResult async)
{
_AllDone.Set();
Socket _Accpt = (Socket)async.AsyncState;
Socket _Handler = _Accpt.EndAccept(async);
StateObject _State = new StateObject();
_State.workSocket = _Handler;
_Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);
}
Solução
Então, se eu entendi direito, você quer Accept
re-início assim que uma conexão de soquete é recebido, e não esperar até Accept
é feito, e é por isso que você não usa a versão sincronização de Accept
.
Então você está dizendo que não dispara o seu método Aceitar quando você conectar um soquete para o endereço especificado e porta? Porque é isso que Aceitar faz: ele aceita uma nova conexão de entrada, esperando até que um cliente se conecta. De modo que pode ser por isso que você está pensando que "caiu" e por isso nunca atinge o seu código em seu Aceite método.
Dica: talvez também ter um olhar para Socket.AcceptAsync
Editar: Para configurar uma escuta servidor assíncrono para conexões de entrada, você não precisa de nenhum ManualWaitEvent:
internal void Initialize(int port,string IP) {
IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Accpt.Bind(_Point);
_Accpt.Listen(2);
_Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
}
private void Accept(IAsyncResult async) {
Socket _Accpt = (Socket)async.AsyncState;
Socket _Handler;
try {
_Handler = _Accpt.EndAccept(async);
} finally {
_Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
}
StateObject _State = new StateObject();
_State.workSocket = _Handler;
_Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);
}
Nota:. Você também vai precisar de uma condição de saída, para que a BeginAccept não é chamado (por exemplo, quando você quer desligar o servidor)
Outras dicas
Eu acho que Lucero está tentando dizer, que a aplicação funciona normalmente, você pode perguntar como vir.
Bem, quando você estiver usando um aplicativo de soquete do lado do servidor, o que você basicamente fazer é pedir ao servidor para liseten a uma porta e esperar por uma conexão para chegar. quando a conexão chega, então você fazer o resto do código.
O que Lucero estava dizendo é que, enquanto nenhuma mensagem está chegando ao servidor o servidor mantém lisetning e espera, que pode olhar para você como se fosse congela.
É o caso em seu código?