A <-> 我 <-> B , A调我的接口,我又去调用B,B给我的回复是异步的,但我又需要同步回复A, 怎么处理

卧槽这是我的昵称吗 2015-05-06 04:19:03
首先。。。 A要求我们必须是同步回复, B给我们的肯定是异步回复, 这点已经改变不了了。。。
________________________________

需求方A通过http请求调用我们的一个接口,并且要求我们同步回复处理结果。

现在的问题是,我们在处理这个请求的时候,会调用另一团队B提供的接口(soap), 但是那个团队处理这个请求的时候,涉及到给硬件写数据,写完数据后是异步返回给我们处理结果(我们再给B提供一个http通信的接口,他们把处理结果发过来)。



问题来了。。。。 我们和硬件组B是异步的,怎么才能同步返回A这个处理结果?

我的想法是。。


A调用我的接口 ->
对这次请求进行编号,然后进行业务处理 ->
调用B组提供的服务让硬件写入数据->
开一个循环(超时机制这里暂时略过不提),隔半秒去数据库读取这个请求编号的处理结果(B组处理完,异步通知我后,我会改变这个请求ID的处理状态为"已处理") ->
某次循环中发现B组已处理完,回复给A处理结果和其他信息。


有更好的办法吗
...全文
404 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
华芸智森 2015-05-08
  • 打赏
  • 举报
回复
A 自旋..
Heart09 2015-05-08
  • 打赏
  • 举报
回复
你把B的功能实现以下,就可以了 说不动你,我就不用你!
  • 打赏
  • 举报
回复
B涉及硬件交互,设计成异步是完全合理的,人家当然不愿意改 倒是A可以去说说,说不动,你就自己设置等待吧,比如上面说的命名事件,或者自己轮询并阻塞线程
於黾 2015-05-07
  • 打赏
  • 举报
回复
思路没有问题 问题是不要跟数据库扯上关系 这完全可以是内存变量(内存数据库)搞定的事情
qzyf1992 2015-05-07
  • 打赏
  • 举报
回复
当然你们老大也有可能因为更高的性能,让主线程不阻塞,把处理数据的结果放在回调函数中,已提高线程的利用率。如果是这样你可以让你们B在回调函数中主动通知你的服务 由于你们是服务与服务的通信 不涉及http协议完全可以利用socket等方式通信,一旦客户端请求过来你调取B的服务 然后阻塞主线程 和B建立另外一个全双工通信并且等待B的通知。。一旦B通知了 数据处理结果 解除阻塞 Response B给你的处理结果。
uinatlex 2015-05-07
  • 打赏
  • 举报
回复
或者一个可以维持长连接的 比如SignalR
uinatlex 2015-05-07
  • 打赏
  • 举报
回复
你和B通信 不用HTTP 不行么
qzyf1992 2015-05-07
  • 打赏
  • 举报
回复
他使用异步操作的目的是想利用icop的方式 在进行磁盘读写的时候 不占据线程 腾出更多的线程做相关逻辑的操作 提高B的吞吐量,当icop执行完毕 windows系统会通过回调函数的方式 通知线程池 重新拿出一个线程来处理回调函数。
qzyf1992 2015-05-07
  • 打赏
  • 举报
回复
你理解错你们老大的意思了 B只是异步的向硬件设备中写入数据 其实主线程是 在同步等待的。 等到数据异步写完之后 会同步把处理结果返回给你。
  • 打赏
  • 举报
回复
引用 8 楼 tcmakebest 的回复:
同步和异步都是可以互相转化的,不要想得太复杂. 同步转异步,就是开线程,异步转同步,就是等啊等. 楼主的问题就是把异步变成同步,建议使用命名事件+限时等待,注意将其中的ID001换成请求ID [/code]
理论和技术都受教了 这方法第一次听说 拿来试试看
紫箫吹散后 2015-05-07
  • 打赏
  • 举报
回复
你们说的好复杂。B这边在回调函数中通知自己。自己这边阻塞掉,等待X秒,再读B返回的结果。 我的理解是: 只有为单一目的设计的单道处理系统,因为硬件上的电路设计支持才能做到 :发生事件后立即被动的实时的得到通知。 而像windows这样的多任务操作系统,想要得知别人异步操作的处理结果,本质上都是轮询看别人搞完没有。 不知道自己理解错了没有。
tcmakebest 2015-05-06
  • 打赏
  • 举报
回复
同步和异步都是可以互相转化的,不要想得太复杂. 同步转异步,就是开线程,异步转同步,就是等啊等. 楼主的问题就是把异步变成同步,建议使用命名事件+限时等待,注意将其中的ID001换成请求ID
private void button1_Click(object sender, EventArgs e)
{
    EventWaitHandle w = new EventWaitHandle(false, EventResetMode.AutoReset, @"Global\ID001");
    bool b = w.WaitOne(10000);/// 调用B接口后进入等待状态
}

private void button2_Click(object sender, EventArgs e)
{
    EventWaitHandle w = new EventWaitHandle(false, EventResetMode.AutoReset, @"Global\ID001");
    w.Set(); /// B接口回调用置信号
}
江南小鱼 2015-05-06
  • 打赏
  • 举报
回复
引用 6 楼 u011710947 的回复:
[quote=引用 5 楼 lovelj2012 的回复:] B异步回复,回复结果搞个标志,比如讲当该标志位是0的时候,你才给A应答 也就是把B的异步当同步来用,待B处理完事才给A应答 针对A的每一个请求,都有相应的实例处理,避免A的多个端点请求造成阻塞。
恩 , 现在就是 “当该标志位是0的时候,你才给A应答”, 怎么去判断标志是否是0? 我就只想到了循环间隔一段时间去查数据库(像starfd说的直接查内存效率更高),这次查到这个标志是0了,然后回复给A[/quote] 你让B完事,Post一个消息给你呗,你循环检索数据库干嘛啊?!
  • 打赏
  • 举报
回复
引用 5 楼 lovelj2012 的回复:
B异步回复,回复结果搞个标志,比如讲当该标志位是0的时候,你才给A应答 也就是把B的异步当同步来用,待B处理完事才给A应答 针对A的每一个请求,都有相应的实例处理,避免A的多个端点请求造成阻塞。
恩 , 现在就是 “当该标志位是0的时候,你才给A应答”, 怎么去判断标志是否是0? 我就只想到了循环间隔一段时间去查数据库(像starfd说的直接查内存效率更高),这次查到这个标志是0了,然后回复给A
江南小鱼 2015-05-06
  • 打赏
  • 举报
回复
B异步回复,回复结果搞个标志,比如讲当该标志位是0的时候,你才给A应答 也就是把B的异步当同步来用,待B处理完事才给A应答 针对A的每一个请求,都有相应的实例处理,避免A的多个端点请求造成阻塞。
  • 打赏
  • 举报
回复
引用 3 楼 rtdb 的回复:
循环读数据库不太好。 用Event.Wait()
关键是B的方法,你调用之后,他先同步给你返回“我收到了,等我慢慢处理”,然后处理完后B在调用我的接口说已经处理完了。。。 我在调B的方法的时候, wait是没用的啊?
rtdb 2015-05-06
  • 打赏
  • 举报
回复
循环读数据库不太好。 用Event.Wait()
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
要么让B给你们再写一个不异步的 要么就跟你自己说的那样阻塞线程,然后你说的是读数据库,其实可以考虑直接从内存数据库中读取结果,异步接收接口更新相应键值对
B是哥。。。我说不动。。。 资历老就是要牛板一点
  • 打赏
  • 举报
回复
要么让B给你们再写一个不异步的 要么就跟你自己说的那样阻塞线程,然后你说的是读数据库,其实可以考虑直接从内存数据库中读取结果,异步接收接口更新相应键值对

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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