liveBook · Manning

Synchronous call

As explained in F# in Action: A Revised Edition of Get Programming with F#

A synchronous operation runs to completion in the caller's execution flow and normally keeps its thread occupied while it waits.

Synchronous programming keeps work in one sequential path: a call returns its result before the next step continues. That straightforward flow makes code easier to write and follow, because functions appear to return immediately and no separate result handler must be coordinated with the initiating code. section 12.1.2

The trade-off appears when a synchronous call waits on external I/O. A database request that takes a second also blocks the application while it waits; in a desktop application, that can freeze the interface. In a web application, each blocked request occupies one of a finite number of available threads. section 12.1.2 section 12.2.1

Use a synchronous operation when its simple, immediate flow fits the interaction; reconsider it when waiting dominates the work:

  • Choose based on request duration, the need for an immediate response, and scalability pressure. section 12.1.1
  • Keep ordinary business logic—working with data, validation, and reshaping—synchronous when it does not need external asynchronous operations. section 12.2.1
  • Treat long-running HTTP or database calls as a warning sign, especially in high-throughput applications. section 12.1.1 section 12.2.1

Database call in a web request

A synchronous ExecuteSql-style database call returns data only after the query finishes, so its executing thread waits throughout the call. With hundreds of incoming requests, those waiting threads cannot serve other requests. An ExecuteSqlAsync-style alternative does not make one query faster; it can let the application handle more requests by reusing resources during the wait. section 12.2.1

Synchronous communication is not inherently wrong. It is the simpler model, while older asynchronous approaches required callbacks, event handlers, or separate paths that had to be manually coordinated, including error handling. The practical question is whether simplicity is worth the waiting cost for the operation at hand. section 12.1.2

Figure 12.1 Comparing synchronous and asynchronous flows. The synchronous flow follows a single, sequential flow. The asynchronous flow branches into two streams, which requires the ability to coordinate the two streams back into one at some point in the future.

Compare the single sequential synchronous path with the branched asynchronous path that later requires coordination. section 12.1.2

How F# in Action: A Revised Edition of Get Programming with F# covers it

How deep it goes
Explains blocking, sequential flow, and thread consequences without implementing synchronous calls.
Examples
Uses database queries, desktop freezes, web requests, and everyday communication media to contrast waiting with asynchronous alternatives.
What you can do after
Evaluate/understand when a blocked synchronous I/O call may harm responsiveness or web-request throughput.
How it connects
Connects synchronous programming to asynchronous programming, external I/O, database calls, threads, and throughput.

Also explained in

Compare how 6 books explain synchronous call →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of F# in Action: A Revised Edition of Get Programming with F#. The section links point to the parts of the book it draws on.