c# SocketAsyncEventArgs下使用ConnectAsync问题

mijiushixin 2017-04-17 05:44:59
最近在研究c#网络通信SocketAsyncEventArgs的使用,有一个问题不明白,代码如下:
SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
connectArgs.UserToken = clientSocket;
connectArgs.RemoteEndPoint = hostEndPoint;
connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);

clientSocket.ConnectAsync(connectArgs);
autoConnectEvent.WaitOne(); //阻塞. 让程序在这里等待,直到连接响应后再返回连接结果

问题如下: clientSocket.ConnectAsync在msdn上说完成可能是同步也可能是异步,但是这边却没有处理同步完成的情况,我不知道是否线程等待是否是会导致这个一定是异步完成IO操作,请各位大侠赐教一下。
...全文
710 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xdashewan 2017-04-18
  • 打赏
  • 举报
回复
引用 4 楼 mijiushixin 的回复:
非常感谢 xuggzu。大概清楚了,意思就是如果如果已经连接了,那么就是同步完成的返回false,如果没有连接那么采用异步来完成socket连接,完成后使用事件 来通知连接了,这边就返回一个true。
你看过msdn上sever端的代码你就很容易理解这个用法,https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx
mijiushixin 2017-04-18
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
不论是这个方法内部是同步或者异步完成了 Connect,实际上都会触发 Completed 事件。
谢谢sp1234,说的非常详细,就是上面这一点我不怎么认同,我理解是如果已经连接了,就是同步完成Connect的,不会触发Completed 事件。如果没有连接,那么它就是异步完成Connect,触发 Completed 事件。
mijiushixin 2017-04-18
  • 打赏
  • 举报
回复
引用 1 楼 xuggzu 的回复:
ConnectAsync采用类似事件的方式通知其状态,从而让用户根据状态来处理后续操作。 所以:autoConnectEvent.WaitOne();这个代码貌似没用,来了连接就告你了,等什么?而且会阻塞线程。
非常感谢 xuggzu。大概清楚了,意思就是如果如果已经连接了,那么就是同步完成的返回false,如果没有连接那么采用异步来完成socket连接,完成后使用事件 来通知连接了,这边就返回一个true。
  • 打赏
  • 举报
回复
我写一个代码举例,比如说
public class A
{
    public event Action testCompleted;

    public void test()
    {
        //
    }
}
你说这个是同步地回调了事件还是异步触发了事件呢? 那么我可能写
public class A
{
    public event Action testCompleted;

    public void test()
    {
        if (testCompleted != null)
            if (DateTime.Now.Ticks % 2 == 0)
                testCompleted();
            else
                ThreadPool.QueueUserWorkItem(h => testCompleted());
    }
}
这里,既可能在调用 test 方法的当前线程立刻同步回调,也可能先让 test 方法执行完,在系统线程池中注册任务来回调事件方法。 从形式上看,事件回调的形式就是异步的,非常适合异步多线程编程。但是我实现 test 方法的内部可能是同步的、可能是异步的,说不定。这也正好说明了回调形式具有很好的流程设计表现力,可以不管内部实现是同步还是异步。
  • 打赏
  • 举报
回复 1
引用 楼主 mijiushixin 的回复:
clientSocket.ConnectAsync(connectArgs); autoConnectEvent.WaitOne(); //阻塞. 让程序在这里等待,直到连接响应后再返回连接结果 问题如下: clientSocket.ConnectAsync在msdn上说完成可能是同步也可能是异步,但是这边却没有处理同步完成的情况,我不知道是否线程等待是否是会导致这个一定是异步完成IO操作,请各位大侠赐教一下。
它所谓的“同步、异步”是指内部ConnectAsync结束机制,而非这里的编程形式。它是指在这条语句返回时就已经连接成功了(本来可以直接用这个方法的返回值继续处理连接)、还是没有连接成功(需要在事件参数中获取并随后继续处理连接)。 例如已经连接好,并不需要向对方发送消息,这个方法就会同步执行完毕。 其实这一层,msdn 作者完全没有“必要”太技术化“,完全没有必要混沌地提这个,说这个反而产生了纠结。本来就是告诉你应该异步编程形式来设计程序就可以了,完全不用管这个方法是否在内部同步完成了。 不论是这个方法内部是同步或者异步完成了 Connect,实际上都会触发 Completed 事件。所以异步形式的代码,不管是内部是ConnectAsync 代码内部是同步还是异步执行的,都无所谓。 但是这里的代码虽然用了一个异步形式的代码,实际上做了一个模拟同步程序才干的低级的设计,也就是“阻塞”。这其实是第二层把水搅浑的做法,而且 msdn 这里直接鲜明地用了最差的代码来写例子。真正异步的设计流程,应该不写 WaitOne,而是真正在 OnConnect 中执行随后的工作。而这里的代码看上去,它这里写了一个 WaitOne,那么很可能在 OnConnect 中只不过是一个 Set 代码,其实就是阻塞,用一个 OnConnect 回调来反过来让你的阻塞信号量能”通过“去执行随后的代码,这是把代码弄复杂了。原本在回调中执行随后的代码就行了。 它这样写 WaitOne 阻塞代码,是假设读者无法理解在 OnConnect 中继续处理后续流程的设计概念。
xuggzu 2017-04-17
  • 打赏
  • 举报
回复
ConnectAsync采用类似事件的方式通知其状态,从而让用户根据状态来处理后续操作。 所以:autoConnectEvent.WaitOne();这个代码貌似没用,来了连接就告你了,等什么?而且会阻塞线程。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧