RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Async-Up Your Objects : Page 3

Encapsulate asynchronous functionality directly into your business objects. The .NET Framework facilitates calling object methods asynchronously through the use of delegates. You may already know how to do this using helper code, but there is a cleaner and much cooler way of packaging this kind of functionality right inside your business objects.

Asynchronous Calling, New and Improved
You've seen how to asynchronously invoke an object's method using a delegate and also how to retrieve the results, whenever they may be available, from a callback routine. You have accomplished this from a client application. If you'd like, you can distribute the FileFunctions object as a component to anyone you like, but it would be up to them to write the plumbing code needed to make asynchronous calls to any of its methods.

Now you're going to learn how to encapsulate most of this into the business object itself. This allows you to distribute the business object as a component and provides the methods needed to invoke the MoveFiles routine, or any other for that matter, asynchronously. You add all this built-in functionality using the standard naming conventions mentioned earlier, which are already in use throughout the .NET Framework. Yes, you guessed it; you will be adding two new methods to the FileFunctions object: BeginMoveFiles and EndMoveFiles. The main advantage of this naming convention is that it is, for the most part, self-explanatory. When you distribute your business object, the reasons for having MoveFiles, BeginMoveFiles, and EndMoveFiles methods will be apparent to anyone who has worked with asynchronous delegates in the past.

So let's get started. The first thing you need to do is declare the delegate as in the previous examples:

In C#:
public delegate bool MoveFilesDelegate(
      string origin, string destination);
Public Delegate Function MoveFilesDelegate( _
      ByVal origin As String, _
      ByVal destination As String) _
      As Boolean
This statement is identical to before; I show it again here because it may be located differently this time. You are assuming that the FileFunctions class may be in a stand-alone component so that it may be distributed later. The delegate declaration must now be accessible to this class without relying on an outside component, so you need to make sure that it is declared somewhere in the component in which this class resides. Keep in mind, a delegate declaration is still made outside the scope of a class. The code for the complete component is in Listing 1 (C#) and Listing 2 (VB .NET).

The next thing to do is add a BeginMoveFiles method to the class. This method has a return type of IAsyncResult, and conforms to the signature you saw in the BeginInvoke method previously. The signature was comprised of the two arguments MoveFiles receives, the AsyncCallback routine and the AsyncState object. Take a look at the method in its entirety and then I'll dissect it piece by piece. Whether you remember the method of asynchronous calling from this article or were already familiar with asynchronous delegate use, the code in this method will make a lot of sense to you.

In C#:
public IAsyncResult BeginMoveFiles(
      string sourceFolder,
      string destinationFolder,
      AsyncCallback callback,
      object asyncState)
      MoveFilesDelegate o_MyDelegate = 
         new MoveFilesDelegate(this.MoveFiles);
      return o_MyDelegate.BeginInvoke( 
         sourceFolder, destinationFolder,
         callback, asyncState);
Public Function BeginMoveFiles( _
      ByVal sourceFolder As String, _
      ByVal destinationFolder As String, _
      ByVal callback As AsyncCallback, _
      ByVal asyncState As Object) _
      As IAsyncResult
      Dim o_MyDelegate As MoveFilesDelegate = _
         New MoveFilesDelegate( _
         AddressOf MoveFiles)
      Return o_MyDelegate.BeginInvoke( _
         sourceFolder, destinationFolder, _
         callback, asyncState)
   End Function
Of course, it looks familiar. Look at the first line of code (after the method declaration). The delegate object is instantiated just like before but with one difference. In the first example, you instantiated FileFunctions and then wired the MoveFiles method into the delegate declaration. The MoveFiles method is not in an instantiated object; instead the MoveFiles method is within this class itself.

The second line invokes the delegate with the ever-popular asynchronous launcher method, BeginInvoke. As before, the signature includes the MoveFiles arguments, the callback routine, and the generic AsyncState object. Note that the variable used to identify the callback came to this function as an argument. Unlike the first example, you do not have to declare an AsyncCallback delegate instance for this routine, because the variable already comes into this method as one. You will see how when I demonstrate the client application's code. The entire instance of the BeginInvoke method is returned to the caller as an implementation of the IAsyncResult interface.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date