Click here to Skip to main content
13,258,269 members (42,607 online)
Click here to Skip to main content

Stats

71.9K views
62 bookmarked
Posted 27 Mar 2006

Server-Side Asynchronous Methods for ASP.NET and WinFX

, 6 Apr 2006
An article that describes how to create server-side asynchronous service methods for ASP.NET and WinFX, thereby freeing up resources on the server to handle more clients simultaenously.
code
ConsoleApplication
Properties
Service References
localhost.map
WebSite
App_Code
Service.svc
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Threading;

/// <summary>
/// Provides methods that count the number of zero bytes in the arial
/// font-file using either a synchronous or asynchronous internal model.
/// </summary>
/// <remarks>This class contains 3 public methods but the WSDL built for this
/// web service will only contain 2 methods.  This is because it will recognise
/// that the BeginAsyncWork and EndAsyncWork methods are two parts of the same
/// method.  You can verify this by running this project and looking at the
/// list of operations shown on the automatic test page that gets generated.</remarks>
[WebService(Namespace = "http://tempuri.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService, IWinfxService
{
	/// <summary>
	/// Performs some work synchronously.
	/// </summary>
	/// <returns>The number of zero bytes in the arial font-file.</returns>
    [WebMethod]
    public Int32 SyncWork() 
	{
		FileStream fs = new FileStream(@"c:\windows\fonts\arialuni.ttf", FileMode.Open);

		try
		{
			Byte[] buffer = new Byte[fs.Length];
			fs.Read(buffer, 0, (Int32) fs.Length);

			Int32 count = 0;
			foreach (Byte b in buffer)
			{
				if (b == 0) count++;
			}
			return count;
		}
		finally
		{
			fs.Close();
		}
	}

	/// <summary>
	/// Performs the first half of the AsyncWork method.
	/// </summary>
	/// <param name="callback">The callback that should be used
	/// notify the ASMX Handler that the background work is complete.</param>
	/// <param name="state">Any object that the ASMX Handler wishes
	/// us to associate with this request.</param>
	/// <returns>An object that implements the IAsyncResult interface which
	/// can be used to query the progress of the background operation.</returns>
	[WebMethod]
	public IAsyncResult BeginAsyncWork(AsyncCallback callback, Object state)
	{
		// create our service state object (that also implements IAsyncResult)
		ServiceState serviceState = new ServiceState();

		// store the callback and state provided by the ASMX handler
		serviceState.HostCallback = callback;
		serviceState.HostState = state;

		// store a reference to the filestream which we're going to use
		serviceState.Stream = new FileStream(@"c:\windows\fonts\arialuni.ttf", FileMode.Open);

		try
		{
			// create a big enough buffer for all the data to be read
			serviceState.Buffer = new Byte[serviceState.Stream.Length];

			// start the background read operation and store the IAsyncResult interface in the state
			serviceState.ReadOperationAsyncResult = serviceState.Stream.BeginRead(serviceState.Buffer, 0, 
				(Int32)serviceState.Stream.Length, 
				 new AsyncCallback(serviceState.ReadOperationComplete), serviceState);
			
			// return our serviceState to the ASMX Handler so it won't be garbage collected and
			// so that we can get at our data in the EndAsyncWork method.
			return serviceState;
		}
		catch (IOException)
		{
			// something went wrong while reading the data so clean up the stream but let
			// the error propogate out so that the ASMX Handler doesn't think it's waiting for
			// callback to be invoked.
			serviceState.Stream.Close();
			throw;
		}
	}

	/// <summary>
	/// Performs the second half of the AysncWork method.
	/// </summary>
	/// <param name="ar">The same object that was returned from the BeginAsyncWork method.</param>
	/// <returns>The number of zero-bytes in the arial font file.</returns>
	[WebMethod]
	public Int32 EndAsyncWork(IAsyncResult ar)
	{
		// we know that the object that implements IAsyncResult in our BeginAsyncWork is a
		// ServiceState object, so perform the cast so that we can get at our member variables.
		ServiceState serviceState = (ServiceState)ar;
		try
		{
			// end the background read operation
			serviceState.Stream.EndRead(serviceState.ReadOperationAsyncResult);
		}
		finally
		{
			// obviously close the stream
			serviceState.Stream.Close();
		}

		// now we can perform whatever work we want to on the buffer that was populated by
		// the background operation.
		Int32 count = 0;
		foreach (Byte b in serviceState.Buffer)
		{
			if (b == 0) count++;
		}
		return count;
	}

	public Service()
	{
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Karl M. Hulme
Web Developer
United Kingdom United Kingdom
I live with my wife in Bournemouth in the UK. She consistently inspires me to be the person I know I should be. I enjoy writing music, playing the piano, watching movies, philisophical discussion and eating jaffa cakes.

You may also be interested in...

Pro
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171114.1 | Last Updated 6 Apr 2006
Article Copyright 2006 by Karl M. Hulme
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid