为什么编辑不能上传图了,附上图链接
1
DOLLOR 2022-05-16 22:34:42 +08:00
拆接口。
前端拿到 json 后,再次用那个 json 请求另一个接口来执行你那个“特别耗时的计算”,等待这个“特别耗时的计算”的同时,前端可以用这个 json 做其他的事情。 |
2
Buges 2022-05-16 22:54:18 +08:00 via Android
你的意思是接口返回的数据不需要等待计算完成,计算的结果不需要返回给前端?
那直接 spawn task 就好了。 |
4
ration 2022-05-16 23:08:50 +08:00 via Android
1.后面的处理另开一个线程
2.使用消息队列 |
5
qtoq126 OP @DOLLOR 拆接口确实是个好方法,只是当拿到第一段 json 然后又马上进行二次请求的时候,前端页面是不是就会暂时卡死?我是希望前端拿到一段 json 后就可以开始展示页面了,用户该干嘛干嘛,然后我后台还在继续算,算完的结果也没必要马上通知给前端,而是当他再度调用到需要这个结果的功能的时候再返回给他
|
6
wunonglin 2022-05-16 23:35:33 +08:00
|
11
Buges 2022-05-17 01:08:48 +08:00 via Android
@qtoq126 那就 spawn 到后台执行的同时返回一个 task id ,前端等待一段时间再用这个 id 请求第二个接口结果,如果尚未完成返回 pending 让前端等待一段时间再次请求。注意第二个接口只返回状态和结果而不要调用执行。
不单单拆接口,所有的接口处理函数中都不要同步等待结果维持连接。你想想你等待的时候连接超时了、中断了,或者用户刷新了重新发送。 |
12
Buges 2022-05-17 01:10:43 +08:00 via Android
所有接口都应该不要阻塞,尽快返回。前端无论如何都不应做“耗时”的请求,即使在后台。
|
13
qtoq126 OP |
14
qtoq126 OP @Buges 谢谢大佬点拨,你说的这个思路我能理解,就是具体到 api 的编写和异步函数的编写上面的话,就不知道怎么去做了
|
15
Buges 2022-05-17 08:00:05 +08:00 via Android
@qtoq126 返回只是结束你这个请求的 handler 函数啊,主程序和后面的线程池都是一直在运行的。除非你是 php 那样用 cgi 一个请求起一个进程。
具体实现很直接啊,第一个接口请求后 Task.Run 把耗时计算 spawn 到后台(不要 await ),并生成一个 UUID ,把这个 UUID 作为 key 和上面返回的 Task 存到一个共享的 ConcurrentDictionary 里面,并把这个 UUID 作为额外的字段加到 json 里返回给前端。 第二个接口前端拿这个 UUID 作为参数请求,拿到后通过这个 UUID 取得上面存的 Task 并检查 Task.Status 是否已经完成,未完成就返回 pending ,完成就返回结果(和释放资源)。 前端请求先第一个接口拿到 json 和 UUID 先渲染,然后等待一段时间在用 UUID 请求第二个接口,如果为 pending 那就等待一段时间重试直到拿到结果。 |
16
frisktale 2022-05-17 09:00:25 +08:00
如果你期望的是”执行步骤 3“且不关心返回值”,可以利用 Hangfile 库的 BackgroundJob.Enqueue 方法。
|
17
frisktale 2022-05-17 09:42:23 +08:00
不对啊,你说的第五点怎么和我印象里的不太一样。我记得,哪怕你不 await ,只要主程序不结束运行,你的异步方法还是会完整的执行下去的,只不过在异步方法的外部没法捕获异常。
|
18
frisktale 2022-05-17 10:25:55 +08:00
|
19
Feiir 2022-05-17 11:30:56 +08:00
成熟的方案就是队列
|