简体   繁体   中英

Does await keyword wait indefinitely or does it have a limit?

If you use the await keyword does it have any limits or does it wait indefinitely for the task to complete?

EDIT: The full context I have is...

A frontend application issues a non async HTTP request to an async Web API endpoint. Ultimately the endpoint will await a call to a stored proc on a db. The frontend application hits a HTTP timeout after probably 100 seconds. If the proc takes 35 minutes to complete,

  1. Will the await method wait 35 minutes for the proc to complete or are there limits?
  2. What happens the await call when the HTTP timeout completes after 100 seconds?
  3. if it continues to run, what happens when the proc returns a response after 35 minutes?

The await keyword waits indefinitely. There is no limit in the awaiting. For example the await below will never proceed to the next line of code. The execution flow will get stuck forever in the await .

await Task.Delay(Timeout.Infinite);
throw new UnreachableException(); // This line is unreachable.

Starting from .NET 6, the Task and Task<TResult> types have a WaitAsync method, that returns a new task which completes after a specified TimeSpan timeout . In case the timeout elapses before the completion of the base task, the WaitAsync task propagates a TimeoutException .

await will wait indefinitely unless the operation itself cancels. While you can cancel that using a CancellationTokenSource or Task.WaitAsync that won't stop the asynchronous operation itself.

In the question's case:

  1. await will keep waiting but
  2. The client's HTTP request will timeout, so await will end with a timeout exception
  3. The endpoints won't notice anything and the stored procedure will keep running for 35 minutes.
  4. Any results will be lost since the client is no longer waiting for them

If you want to actually cancel the stored procedure you'll have to modify the endpoint to handle a cancellation request and somehow cancel the stored procedure

One way to do this would be to signal the worker code that executes the stored procedure to cancel. Cancelling an ExecuteNonQuery call wont' cancel the stored procedure itself, but if the code runs with an explicit database transaction, the cancellation exception will abort the transaction and the stored procedure.

Another option is to kill the database session that executes the stored procedure. This will require some bookkeeping, to store the session ID of the executing connection before the call to ExecuteNonQuery .

Stephen Toub describes these implications in How do I cancel non-cancelable async operations? . The conclusion is

So, can you cancel non-cancelable operations? No. Can you cancel waits on non-cancelable operations? Sure… just be very careful when you do.

What about asynchronous Web APIs?

To paraphrase Simon Wardley What does this mean ?

ASP.NET Web APIs with async actions?

Those are still RPC-style APIs that just allow the action to use the async keyword. If the client times out, it won't be able to receive results

Request-Reply style

In this case the client, eg an Angular or Reactjs SPA sends a request to the server and after half an hour the server sends a reply to the client using WebSockets or SignalR.

That's truly asynchronous and the response won't be lost. This requires a different client design, separating the request from the response code. Quite often that can simplify the client though, as the request code no longer has to handle timeout failure cases.

With a bit of care, responses can be sent through SignalR to specific Client/User IDs, not just the requesting client, so that even if the browser closes in the mean time, a new client could receive the results.

Other technologies that can be used for this are Server-Sent events and Push API notifications.

Polling for status

Not very scalable for either client or server. In this case the client starts a request, eg a job and gets back a token. The client polls the server for the job's status. That's very expensive on server resources.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM