Asynchronous method invocation

Last updated

In multithreaded computer programming, asynchronous method invocation (AMI), also known as asynchronous method calls or the asynchronous pattern is a design pattern in which the call site is not blocked while waiting for the called code to finish. Instead, the calling thread is notified when the reply arrives. Polling for a reply is an undesired option.

Contents

Background

AMI is a design pattern for asynchronous invocation of potentially long-running methods of an object. [1] It is equivalent to the IOU ("I owe you") pattern described in 1996 by Allan Vermeulen. [2] [3]

In most programming languages a called method is executed synchronously, i.e. in the thread of execution from which it is invoked. If the method takes a long time to complete, e.g. because it is loading data over the internet, the calling thread is blocked until the method has finished. When this is not desired, it is possible to start a "worker thread" and invoke the method from there. In most programming environments this requires many lines of code, especially if care is taken to avoid the overhead that may be caused by creating many threads. AMI solves this problem in that it augments a potentially long-running ("synchronous") object method with an "asynchronous" variant that returns immediately, along with additional methods that make it easy to receive notification of completion, or to wait for completion at a later time.

One common use of AMI is in the active object design pattern. Alternatives are synchronous method invocation and future objects. [4] An example for an application that may make use of AMI is a web browser that needs to display a web page even before all images are loaded.

Since method is a special case of procedure, asynchronous method invocation is a special case of asynchronous procedure call.

Implementations

Java class

FutureTask class [5] in Java use events to solve the same problem. This pattern is a variant of AMI whose implementation carries more overhead, but it is useful for objects representing software components.

.NET Framework

Example

The following example is loosely based on a standard AMI style used in the .NET Framework. [9] Given a method Accomplish, one adds two new methods BeginAccomplish and EndAccomplish:

classExample{ResultAccomplish(args)IAsyncResultBeginAccomplish(args)ResultEndAccomplish(IAsyncResulta)}

Upon calling BeginAccomplish, the client immediately receives an object of type AsyncResult (which implements the IAsyncResult interface), so it can continue the calling thread with unrelated work. In the simplest case, eventually there is no more such work, and the client calls EndAccomplish (passing the previously received object), which blocks until the method has completed and the result is available. [10] The AsyncResult object normally provides at least a method that allows the client to query whether the long-running method has already completed:

interfaceIAsyncResult{boolHasCompleted()}

One can also pass a callback method to BeginAccomplish, to be invoked when the long-running method completes. It typically calls EndAccomplish to obtain the return value of the long-running method. A problem with the callback mechanism is that the callback function is naturally executed in the worker thread (rather than in the original calling thread), which may cause race conditions. [11] [12]

In the .NET Framework documentation, the term event-based asynchronous pattern refers to an alternative API style (available since .NET 2.0) using a method named AccomplishAsync instead of BeginAccomplish. [13] [14] A superficial difference is that in this style the return value of the long-running method is passed directly to the callback method. Much more importantly, the API uses a special mechanism to run the callback method (which resides in an event object of type AccomplishCompleted) in the same thread in which BeginAccomplish was called. This eliminates the danger of race conditions, making the API easier to use and suitable for software components; on the other hand this implementation of the pattern comes with additional object creation and synchronization overhead. [15]

Related Research Articles

Visual Basic .NET Object-oriented computer programming language

Visual Basic, originally called Visual Basic .NET (VB.NET), is a multi-paradigm, object-oriented programming language, implemented on .NET, Mono, and the .NET Framework. Microsoft launched VB.NET in 2002 as the successor to its original Visual Basic language, the last version of which was Visual Basic 6.0. Although the ".NET" portion of the name was dropped in 2005, this article uses "Visual Basic [.NET]" to refer to all Visual Basic languages released since 2002, in order to distinguish between them and the classic Visual Basic. Along with C# and F#, it is one of the three main languages targeting the .NET ecosystem. As of March 11, 2020, Microsoft announced that evolution of the VB.NET language has concluded.

F Sharp (programming language) Microsoft programming language

F# is a functional-first, general purpose, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.

Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes.

In computer programming, a callback, also known as a "call-after" function, is any reference to executable code that is passed as an argument to other code; that other code is expected to call back (execute) the code at a given time. This execution may be immediate as in a synchronous callback, or it might happen at a later point in time as in an asynchronous callback. Programming languages support callbacks in different ways, often implementing them with subroutines, lambda expressions, blocks, or function pointers.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

In computer science, message passing is a technique for invoking behavior on a computer. The invoking program sends a message to a process and relies on that process and its supporting infrastructure to then select and run some appropriate code. Message passing differs from conventional programming where a process, subroutine, or function is directly invoked by name. Message passing is key to some models of concurrency and object-oriented programming.

The event dispatching thread (EDT) is a background thread used in Java to process events from the Abstract Window Toolkit (AWT) graphical user interface event queue. It is an example of the generic concept of event-driven programming, that is popular in many other contexts than Java, for example, web browsers, or web servers.

In computer science, asynchronous I/O is a form of input/output processing that permits other processing to continue before the transmission has finished.

In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is initially unknown, usually because the computation of its value is not yet complete.

RPyC Python library

RPyC, or Remote Python Call, is a Python library for remote procedure calls (RPC), as well as distributed computing. Unlike regular RPC mechanisms, such as ONC RPC, CORBA or Java RMI, RPyC is transparent, symmetric, and requires no special decoration or definition languages. Moreover, it provides programmatic access to any pythonic element, be it functions, classes, instances or modules.

.NET Remoting is a Microsoft application programming interface (API) for interprocess communication released in 2002 with the 1.0 version of .NET Framework. It is one in a series of Microsoft technologies that began in 1990 with the first version of Object Linking and Embedding (OLE) for 16-bit Windows. Intermediate steps in the development of these technologies were Component Object Model (COM) released in 1993 and updated in 1995 as COM-95, Distributed Component Object Model (DCOM), released in 1997, and COM+ with its Microsoft Transaction Server (MTS), released in 2000. It is now superseded by Windows Communication Foundation (WCF), which is part of the .NET Framework 3.0.

The active object design pattern decouples method execution from method invocation for objects that each reside in their own thread of control. The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests.

Concurrency and Coordination Runtime (CCR) is an asynchronous programming library based on .NET Framework from Microsoft distributed with Microsoft Robotics Developer Studio (MRDS). Even though it comes with MRDS, it is not limited to modelling robotic behavior but can be used to express asynchronous behavior in any application.

Joins is an asynchronous concurrent computing API (Join-pattern) from Microsoft Research for the .NET Framework. It is based on join calculus and makes the concurrency constructs of the Cω language available as a CLI assembly that any CLI compliant language can use.

Grand Central Dispatch, is a technology developed by Apple Inc. to optimize application support for systems with multi-core processors and other symmetric multiprocessing systems. It is an implementation of task parallelism based on the thread pool pattern. The fundamental idea is to move the management of the thread pool out of the hands of the developer, and closer to the operating system. The developer injects "work packages" into the pool oblivious of the pool's architecture. This model improves simplicity, portability and performance.

Node.js JavaScript runtime environment

Node.js is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting—running scripts server-side to produce dynamic web page content before the page is sent to the user's web browser. Consequently, Node.js represents a "JavaScript everywhere" paradigm, unifying web-application development around a single programming language, rather than different languages for server-side and client-side scripts.

Windows Runtime (WinRT) is a platform-agnostic component and application architecture first introduced in Windows 8 and Windows Server 2012 in 2012. It is implemented in C++ and officially supports development in C++, Rust/WinRT, Python/WinRT, JavaScript-TypeScript, and the managed code languages C# and Visual Basic .NET (VB.NET).

Join-patterns provides a way to write concurrent, parallel and distributed computer programs by message passing. Compared to the use of threads and locks, this is a high level programming model using communication constructs model to abstract the complexity of concurrent environment and to allow scalability. Its focus is on the execution of a chord between messages atomically consumed from a group of channels.

In computer programming, the async/await pattern is a syntactic feature of many programming languages that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function. It is semantically related to the concept of a coroutine and is often implemented using similar techniques, and is primarily intended to provide opportunities for the program to execute other code while waiting for a long-running, asynchronous task to complete, usually represented by promises or similar data structures. The feature is found in C# 5.0, C++, Python 3.5, F#, Hack, Julia, Dart, Kotlin 1.1, Rust 1.39, Nim 0.9.4, JavaScript ES2017, Swift 5.5 and Zig, with some experimental work in extensions, beta versions, and particular implementations of Scala.

Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigated by a program that take place concurrently with program execution, without the program blocking to wait for results. Asynchronous input/output is an example of the latter case of asynchrony, and lets programs issue commands to storage or network devices that service these requests while the processor continues executing the program. Doing so provides a degree of parallelism.

References

  1. "Asynchronous Method Invocation". Distributed Programming with Ice. ZeroC, Inc. Archived from the original on 5 January 2008. Retrieved 22 November 2008.
  2. Vermeulen, Allan (June 1996). "An Asynchronous Design Pattern". Dr. Dobb's Journal . Retrieved 22 November 2008.
  3. Nash, Trey (2007). "Threading in C#". Accelerated C# 2008. Apress. ISBN   978-1-59059-873-3.
  4. Lavender, R. Greg; Douglas C. Schmidt. "Active Object" (PDF). Archived from the original (PDF) on 2012-09-24. Retrieved 22 November 2008.{{cite journal}}: Cite journal requires |journal= (help)
  5. "Class FutureTask". Oracle. 2011. Archived from the original on 2013-06-25. Retrieved 2015-06-29.
  6. "Asynchronous Programming Model". Microsoft. 2015. Retrieved 2015-06-29.
  7. "Event-based Asynchronous Pattern Overview". Microsoft. 2015. Retrieved 2015-06-29.
  8. "Task-based Asynchronous Pattern". Microsoft. 2015. Retrieved 2015-06-29.
  9. "Asynchronous Programming Design Patterns". .NET Framework Developer's Guide. Microsoft Developer Network. Archived from the original on 22 November 2008. Retrieved 22 November 2008.
  10. "Asynchronous Programming Overview". .NET Framework Developer's Guide. Microsoft Developer Network. Archived from the original on 7 December 2008. Retrieved 22 November 2008.
  11. "Using an AsyncCallback Delegate to End an Asynchronous Operation". .NET Framework Developer's Guide. Microsoft Developer Network. Archived from the original on 23 December 2008. Retrieved 22 November 2008.
  12. "Concurrency Issues". Distributed Programming with Ice. ZeroC, Inc. Archived from the original on 28 March 2008. Retrieved 22 November 2008.
  13. Christian Nagel; Bill Evjen; Jay Glynn; Karli Watson & Morgan Skinner (2008). "Event-based Asynchronous Pattern". Professional C# 2008 . Wiley. pp.  570–571. ISBN   9780470191378.
  14. "Multithreaded Programming with the Event-based Asynchronous Pattern". .NET Framework Developer's Guide. Microsoft Developer Network. Archived from the original on 25 December 2008. Retrieved 22 November 2008.
  15. "Deciding When to Implement the Event-based Asynchronous Pattern". .NET Framework Developer's Guide. Microsoft Developer Network. Archived from the original on 22 November 2008. Retrieved 22 November 2008.

Further reading