wait 关键字是无限期等待还是有限制?

Fre*_*020 3 c# async-await

如果您使用await关键字,它是否有任何限制,或者是否无限期地等待任务完成?

编辑:我拥有的完整上下文是......

前端应用程序向异步 Web API 端点发出非异步 HTTP 请求。最终,端点将等待对数据库上存储过程的调用。前端应用程序可能在 100 秒后遇到 HTTP 超时。如果该过程需要 35 分钟才能完成,

  1. wait 方法是否会等待 35 分钟才能完成过程,还是有限制?
  2. 当 HTTP 超时在 100 秒后完成时,await 调用会发生什么情况?
  3. 如果继续运行,35分钟后proc返回响应时会发生什么?

The*_*ias 8

关键字await无限期地等待。等待是没有限制的。例如,await下面的代码永远不会继续到下一行代码。执行流程将永远卡在await.

await Task.Delay(Timeout.Infinite);
throw new UnreachableException(); // This line is unreachable.
Run Code Online (Sandbox Code Playgroud)

从 .NET 6 开始,TaskTask<TResult>类型有一个WaitAsync方法,该方法返回一个新任务,该任务在指定的TimeSpan timeout. 如果在timeout基本任务完成之前经过,该WaitAsync任务将传播一个TimeoutException.


Pan*_*vos 5

await将无限期地等待,除非操作本身取消。虽然您可以使用 CancellationTokenSource 或Task.WaitAsync不会停止异步操作本身。

\n

在问题的情况下:

\n
    \n
  1. await会继续等待但是
  2. \n
  3. 客户端的HTTP请求会超时,所以await会以超时异常结束
  4. \n
  5. 端点不会注意到任何事情,存储过程将继续运行 35 分钟。
  6. \n
  7. 任何结果都将丢失,因为客户端不再等待它们
  8. \n
\n

如果您想实际取消存储过程,则必须修改端点以处理取消请求并以某种方式取消存储过程

\n

执行此操作的一种方法是向执行存储过程的工作代码发出信号以取消。取消ExecuteNonQuery不会取消存储过程本身,但如果代码使用显式数据库事务运行,则取消异常将中止事务和存储过程。

\n

另一种选择是终止执行存储过程的数据库会话。这将需要一些簿记,以便在调用之前存储正在执行的连接的会话 IDExecuteNonQuery

\n

Stephen Toub 在如何取消不可取消的异步操作?中描述了这些含义。。结论是

\n
\n

那么,可以取消不可取消的操作吗?不可以。您可以取消不可取消操作的等待吗?当然\xe2\x80\xa6,但你这样做时要非常小心。

\n
\n

异步 Web API 怎么样?

\n

套用西蒙·沃德利的话What does this mean

\n

带有操作的 ASP.NET Web API async

\n

这些仍然是 RPC 风格的 API,只允许操作使用关键字async。如果客户端超时,将无法收到结果

\n

请求-回复风格

\n

在这种情况下,客户端(例如 Angular 或 Reactjs SPA)向服务器发送请求,半小时后服务器使用 WebSockets 或 SignalR 向客户端发送回复。

\n

这确实是异步的,并且响应不会丢失。这需要不同的客户端设计,将请求与响应代码分开。但这通常可以简化客户端,因为请求代码不再需要处理超时失败情况。

\n

稍加注意,响应可以通过 SignalR 发送到特定的客户端/用户 ID,而不仅仅是请求客户端,这样即使浏览器同时关闭,新客户端也可以收到结果。

\n

其他可用于此目的的技术包括服务器发送事件和推送 API 通知。

\n

轮询状态

\n

对于客户端或服务器来说可扩展性都不是很好。在这种情况下,客户端启动一个请求,例如一个作业并取回一个令牌。客户端向服务器轮询作业的状态。这对服务器资源来说非常昂贵。

\n