Home > Refactorings > Refactorings to execute statements asynchronously

Refactorings to execute statements asynchronously

September 17th, 2012

In continuing with the ‘Refactorings for simplifying of the .NET 4.0 parallel computing development‘ thread, let’s review the additional refactoring for executing statements asynchronously called in the same manner – Execute Statement Asynchronously. The refactoring is available in two versions:

  • Execute Statement Asynchronously (FromAsync)
  • Execute Statement Asynchronously (StartNew)

The FromAsync version of the refactoring launches an asynchronous operation passing a pair of the corresponding BeginXxx and EndXxx methods of the selected statement to the FromAsync call of the Task.Factory. The FromAsync call provides a convenient mechanism which uses the BeginXxx and EndXxx methods of the Asynchronous Programming Model (APM) to create a Task.

The TaskFactory simplifies creation and startup of simple background tasks dramatically. For example, consider that we have a Stream and a byte buffer, and we want to read from that stream into the buffer. Synchronously, we could do the following:

CodeRush Execute Statement Asynchronously Sample Code

The Execute Statement Asynchronously (FromAsync) refactoring will allow us to convert this code into the FromAsync call:

CodeRush Execute Statement Asynchronously FromAsync Preview

resulting in the following one:

CodeRush Execute Statement Asynchronously FromAsync Result

The FromAsync call returns a handle to the associated Task. The resulting Task object will, by default, be executed on a thread pool thread. Combine this support with the ability to do Task.WaitAll, Task.WaitAny, Task.Factory.ContinueWhenAll, and Task.Factory.ContinueWhenAny, and we can achieve a very useful synchronization functionality having just a little code.

The second version of the refactoring (StartNew) launches an asynchronous operation by passing the current statement to the StartNew method of Task.Factory. For instance, using StartNew is more efficient than creating and starting tasks manually, because the StartNew method not only starts a new task but also applies the required synchronization to the process. If you construct a task using the Task’s constructor, you then pay this synchronization cost when calling the Start method, because you need to have protection against the chance that another thread is concurrently calling Start. However, if we use the Task.Factory.StartNew, we know that the task will have already been scheduled and started by the time we get the Task reference returned, which means that it is no longer possible for threads to race to call Start, because every call to Start will fail. In the case of using StartNew, we can avoid the additional synchronization and take a faster and easier approach for scheduling a Task.

The Execute Statement Asynchronously (StartNew) refactoring can be applied on any statement:

CodeRush Execute Statement Asynchronously StartNew Preview

which will result in:

CodeRush Execute Statement Asynchronously StartNew Result

The difference between the StartNew and FromAsync methods is that using the latter for the things like Stream (i.e., when API offers the appropriate BeginXxx and EndXxx methods), you will actually end up using the async I/O underneath the covers, e.g., I/O Completion Ports in Windows which provide an efficient threading model for processing multiple asynchronous I/O requests on a multiprocessor system. The FromAsync method in this case provides the best way to achieve I/O scalability, and is more efficient than blocking multiple CPU threads doing a synchronous operation using the StartNew method.

—–
Products: CodeRush Pro
Versions: 12.1 and up
VS IDEs: 2008 and up
Updated: Sep/17/2012
ID: R069

Similar Posts:

  1. MartinHT
    September 21st, 2012 at 09:26 | #1

    Fatal error: Uncaught Error: Call to undefined function eregi_replace() in H:\root\home\megazoid-001\www\skorkincom\wp-content\plugins\bbcomments\BBComments.php:41 Stack trace: #0 H:\root\home\megazoid-001\www\skorkincom\wp-includes\class-wp-hook.php(289): render_comment() #1 H:\root\home\megazoid-001\www\skorkincom\wp-includes\plugin.php(212): WP_Hook->apply_filters() #2 H:\root\home\megazoid-001\www\skorkincom\wp-includes\comment-template.php(1028): apply_filters() #3 H:\root\home\megazoid-001\www\skorkincom\wp-content\themes\inove\functions.php(1163): comment_text() #4 H:\root\home\megazoid-001\www\skorkincom\wp-includes\class-walker-comment.php(179): custom_comments() #5 H:\root\home\megazoid-001\www\skorkincom\wp-includes\class-wp-walker.php(144): Walker_Comment->start_el() #6 H:\root\home\megazoid-001\www\skorkincom\wp-includes\class-walker-comment.php(139): Walker->display_element() #7 H:\root\home\megazoid-001\www\skorkincom\wp-includes\class-wp-walker.php(332): Walker_Comment->display_element() #8 H:\root\home\me in H:\root\home\megazoid-001\www\skorkincom\wp-content\plugins\bbcomments\BBComments.php on line 41
    WordPress › Error

    There has been a critical error on this website.

    Learn more about debugging in WordPress.