怎样封装异步操作?(使异步操作具有和同步操作类似的接口)

时间:2021-10-30 19:35:23
比如说,在程序中需要执行一个操作Action(),这个操作的执行过程大致是这样的:
1:客户端向服务器请求数据,并等待服务器的响应
2:客户端接收服务器传送过来的数据
3:客户端根据服务器传送的数据执行相应的操作
虽然客户端和服务器之间数据的交换使用的是异步的方式,但是要求调用Action()的时候,只要像调用普通函数一样一句"Action();"就可以,Action()在实现完所有功能以后返回,就是说,对于调用者来说,整个过程就像是执行一次同步操作。

现在用的是WaitForSingleObject那些方法,但是因为第一次接触这些,所以做的很粗糙,代码难看到自己都看不下去了,所以希望能得到前辈的指导,非常感谢~

6 个解决方案

#1


如果是另开线程的方式来做异步操作的话,等待线程返回就可以了

#2


LZ 使用 WaitForSingleObject 方法正确啊,LZ具体的异步操作用的是哪种方式?

#3


程序中有一个专门的模块负责和服务器通讯,在那个模块接收到数据以后,通过调用我的模块提供的OnReceive()方法将接收到的数据传递给我,这样的。
我现在的处理是,在SendData()方法中发送完数据以后,调用WaitForSingleObject()挂起线程,然后当OnReceive()方法被调用并且接收到数据以后使用SetEvent()恢复SendData()所在的线程。虽然程序可以获得正确的结果,但是总感觉这种做法比较难看,不知道还有没有更加好看一些的方法。

#4


没什么难看的,所谓“封装”,就是只给人看外面,里面其实是很乱的,你现在的做法还不算乱。

#5


信号量

#6


引用楼主 Silenker 的帖子:
比如说,在程序中需要执行一个操作Action(),这个操作的执行过程大致是这样的: 
1:客户端向服务器请求数据,并等待服务器的响应 
2:客户端接收服务器传送过来的数据 
3:客户端根据服务器传送的数据执行相应的操作 
虽然客户端和服务器之间数据的交换使用的是异步的方式,但是要求调用Action()的时候,只要像调用普通函数一样一句"Action();"就可以,Action()在实现完所有功能以后返回,就是说,对于调用者来说,整个过程…


异步,基本都是执行后马上就返回API执行结果(返回的是正在执行或执行出错这两结果).如果返回的是"正在执行"的结果,那么最终结果会是以消息或信号最终返回给你的程序,但你所说的Action(),不可能得到最后执行结果,因为Action()执行完,Action()里面执行的API系统很可能还在执行中.举个例子:
BOOL Action()
{
 //这里是一个异步的连接目标服务器 
 WSAAsyncSelect(DataSocket,WindowHandle,WM_SOCKET,FD_CONNECT);
 INT Len = sizeof(ServerAddress);
 if (connect(DataSocket,(const SOCKADDR *)&ServerAddress,Len) == SOCKET_ERROR)
 {
 if (WSAGetLastError() != WSAEWOULDBLOCK)
 {
 closesocket(DataSocket);
     return FALSE;
 }
 }
 return TRUE; //   就算返回TRUE,只代表connect正在执行中,不代表连接上目标服务器
}
在你执行connect()这API后,只是执行使用异步connect()这个API返回结果,如果没出错,最终结果你要通过获取FD_CONNECT消息去确认是否连接上或出现错误.

#1


如果是另开线程的方式来做异步操作的话,等待线程返回就可以了

#2


LZ 使用 WaitForSingleObject 方法正确啊,LZ具体的异步操作用的是哪种方式?

#3


程序中有一个专门的模块负责和服务器通讯,在那个模块接收到数据以后,通过调用我的模块提供的OnReceive()方法将接收到的数据传递给我,这样的。
我现在的处理是,在SendData()方法中发送完数据以后,调用WaitForSingleObject()挂起线程,然后当OnReceive()方法被调用并且接收到数据以后使用SetEvent()恢复SendData()所在的线程。虽然程序可以获得正确的结果,但是总感觉这种做法比较难看,不知道还有没有更加好看一些的方法。

#4


没什么难看的,所谓“封装”,就是只给人看外面,里面其实是很乱的,你现在的做法还不算乱。

#5


信号量

#6


引用楼主 Silenker 的帖子:
比如说,在程序中需要执行一个操作Action(),这个操作的执行过程大致是这样的: 
1:客户端向服务器请求数据,并等待服务器的响应 
2:客户端接收服务器传送过来的数据 
3:客户端根据服务器传送的数据执行相应的操作 
虽然客户端和服务器之间数据的交换使用的是异步的方式,但是要求调用Action()的时候,只要像调用普通函数一样一句"Action();"就可以,Action()在实现完所有功能以后返回,就是说,对于调用者来说,整个过程…


异步,基本都是执行后马上就返回API执行结果(返回的是正在执行或执行出错这两结果).如果返回的是"正在执行"的结果,那么最终结果会是以消息或信号最终返回给你的程序,但你所说的Action(),不可能得到最后执行结果,因为Action()执行完,Action()里面执行的API系统很可能还在执行中.举个例子:
BOOL Action()
{
 //这里是一个异步的连接目标服务器 
 WSAAsyncSelect(DataSocket,WindowHandle,WM_SOCKET,FD_CONNECT);
 INT Len = sizeof(ServerAddress);
 if (connect(DataSocket,(const SOCKADDR *)&ServerAddress,Len) == SOCKET_ERROR)
 {
 if (WSAGetLastError() != WSAEWOULDBLOCK)
 {
 closesocket(DataSocket);
     return FALSE;
 }
 }
 return TRUE; //   就算返回TRUE,只代表connect正在执行中,不代表连接上目标服务器
}
在你执行connect()这API后,只是执行使用异步connect()这个API返回结果,如果没出错,最终结果你要通过获取FD_CONNECT消息去确认是否连接上或出现错误.