首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用EAP时线程安全事件

使用EAP时线程安全事件
EN

Code Review用户
提问于 2014-04-01 03:05:19
回答 1查看 182关注 0票数 3

这是使用EAP (套接字)的服务器的代码。

AsyncOperation.Post是引发线程安全事件的正确方式吗?

AsyncOperation.Post声明:

在适合应用程序模型的线程或上下文上调用委托。

在代码中是否还有其他错误(比如可以改进的地方,或者是一件不好的事情)?

代码语言:javascript
复制
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();
        }
    }
}
EN

回答 1

Code Review用户

发布于 2015-12-14 14:01:20

公共EndPoint LocalEndPoing { get;私有集;}

应该是LocalEndPoint

公开无效开始(){尝试{如果(收听)返回;

为什么if语句在try..catch中?这是可以肯定的,这不会抛出任何例外。根据经验,只将代码放入可以抛出的try..catch中。

您应该始终使用大括号{},尽管它们可能是可选的,以减少代码出错的可能性。

_server.Listen(10);

为什么是10而不是1000?应该避免使用神奇的数字,以使代码更容易阅读和理解。您应该将神奇的数字/字符串提取到有意义的变量/常量中,这样维护者Sam就会第一眼看到这是关于什么的。

_asyncOperation.Post(ex=>OnErrorOccured(ex作为例外),Exception);

让您的变量和运算符有一些喘息的空间,这样只会使您的代码更具可读性。

代码语言:javascript
复制
_asyncOperation.Post(ex => OnErrorOccured(ex as Exception), exception);  

私有空_acceptArg_Completed(对象发送方,SocketAsyncEventArgs e)

有下划线前缀的方法名是“否”。只允许类级变量名使用下划线前缀。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/45907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档