This is my code for a server using EAP (Sockets).
Is AsyncOperation.Post is the right way to raise thread safe events?
AsyncOperation.Post states:
Invokes a delegate on the thread or context appropriate for the application model.
PS: Is there any other mistake in the code i.e something that can be improved or is a bad thing to do?
public sealed class Server
{
private Socket _server;
private SocketAsyncEventArgs _acceptArg;
private AsyncOperation _asyncOperation;
public EndPoint LocalEndPoing { get; private set; }
public bool Listening { get; private set; }
public delegate void ErrorOccuredEventHandler(Server sender, Exception e);
public delegate void ClientConnectedEventHandler(Server sender, EndPoint remoteEndpoint);
public event ErrorOccuredEventHandler ErrorOcurred;
public event ClientConnectedEventHandler ClientConnected;
private void OnErrorOccured(Exception e)
{
if(ErrorOcurred!=null)
ErrorOcurred.Invoke(this,e);
}
private void OnClientConnected(EndPoint remoteEndPoint)
{
if(ClientConnected!=null)
ClientConnected.Invoke(this,remoteEndPoint);
}
public Server(EndPoint localEndPoint)
{
LocalEndPoing = localEndPoint;
Listening = false;
_asyncOperation = AsyncOperationManager.CreateOperation(null);
}
public void Start()
{
try
{
if (Listening)
return;
_server = _server ?? new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_server.Bind(LocalEndPoing);
_server.Listen(10);
Listening = true;
_acceptArg = _acceptArg ?? new SocketAsyncEventArgs();
_acceptArg.Completed += _acceptArg_Completed;
if (!_server.AcceptAsync(_acceptArg))
_acceptArg_Completed(null, _acceptArg);
}
catch (Exception exception)
{
_asyncOperation.Post(ex=>OnErrorOccured(ex as Exception),exception);
}
}
public void Stop()
{
try
{
if(!Listening)
return;
_server.Close();
_acceptArg.Dispose();
_server = null;
_acceptArg = null;
Listening = false;
}
catch (Exception exception)
{
_asyncOperation.Post(ex => OnErrorOccured(ex as Exception), exception);
}
}
private void _acceptArg_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
_asyncOperation.Post(remoteEndPoint=>OnClientConnected(remoteEndPoint as EndPoint),e.AcceptSocket.RemoteEndPoint);
//Do nasty things with the accepted socket
e.AcceptSocket = null;
if(!_server.AcceptAsync(e))
_acceptArg_Completed(null,e);
}
else
{
_asyncOperation.Post(ex => OnErrorOccured(ex as Exception), new SocketException((int)e.SocketError));
Stop();
}
}
}