Click here to Skip to main content
13,146,742 members (92,664 online)
Click here to Skip to main content

Stats

45.4K views
807 downloads
99 bookmarked
Posted 19 Nov 2008

Automatic Implementation of the Event-Based Asynchronous Pattern

, 26 Nov 2008
Implement the event-based asynchronous pattern automatically with this code generator
asyncgen_demo
ClassLibrary1
bin
Debug
ClassDiagram.cd
Properties
Client
bin
Debug
Properties
Server
bin
Debug
Properties
asyncgen_src
AsyncClientGeneratorLib
asyncgen.snk
ClassDiagram.cd
fxReflection.proj
Properties
Properties
TestAssembly
Properties
TestClientCpp
app.ico
TestClientCSharp
Properties
TestClientVB
My Project
Application.myapp
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace AsyncGen
{
    /// <summary>
    /// Indicates to AsyncGen that it should process this method and allows you to customize the generated code.
    /// </summary>
	[AttributeUsage(AttributeTargets.Method)]
	public sealed class GenerateAsyncOperationAttribute : Attribute
	{
        /// <summary>
        /// Default constructor.
        /// </summary>
		public GenerateAsyncOperationAttribute()
		{
		}

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="baseName">Same as the <see cref="BaseName"/> property.</param>
		public GenerateAsyncOperationAttribute(string baseName)
		{
			this.baseName = baseName;
		}

        /// <summary>
        /// Gets or sets a string that is used to name the client class members that implement this asynchronous operation.
        /// </summary>
        /// <remarks><para>If this property is not specified, the base name is the name of the original method.</para>
        /// <para>If a method is overloaded, use a different base name for each overload.</para></remarks>
        public string BaseName
        {
            get { return baseName; }
            set { baseName = value; }
        }

        /// <summary>
        /// Gets or sets the name of the method used to start the asynchronous operation.
        /// </summary>
        /// <remarks>If this property is not specified, the name of the method is &lt;<see cref="BaseName"/>&gt;Async.</remarks>
        public string StartMethodName
        {
            get { return startMethodName; }
            set { startMethodName = value; }
        }

        /// <summary>
        /// Gets or sets the name of the event to raise when the operation has completed.
        /// </summary>
        /// <remarks>If this property is not specified, the name of the event is &lt;<see cref="BaseName"/>&gt;Completed.</remarks>
        public string CompletedEventName
        {
            get { return completedEventName; }
            set { completedEventName = value; }
        }

        /// <summary>
        /// Gets or sets the name of the structure that holds the output of the operation.
        /// </summary>
        /// <remarks>If this property is not specified, the name of the structure is &lt;<see cref="BaseName"/>&gt;Output.</remarks>
        public string OutputTypeName
        {
            get { return outputTypeName; }
            set { outputTypeName = value; }
        }

        /// <summary>
        /// Gets or sets the name of the method that the application should call to cancel the operation.
        /// </summary>
		/// <remarks>
        /// <para>If this property is not specified, the name of the method is &lt;<see cref="BaseName"/>&gt;AsyncCancel.</para>
        /// <para><list>
		/// <item>If CancelMethodName == <c>null</c>, don't generate a Cancel method.</item>
		/// <item>If CancelMethodName == <see cref="String.Empty"/>, use the base name to construct the Cancel method name.</item>
		/// </list></para>
        /// <para>When you set <see cref="CancelMethodName"/> to any non-null value, <see cref="GenerateCancelMethod"/> is set to <c>true</c>.</para>
        /// <para>When you set <see cref="GenerateCancelMethod"/> to <c>true</c>, the name of the cancel method is set to &lt;<see cref="BaseName"/>&gt;AsyncCancel.</para>
        /// <para>Use either <see cref="CancelMethodName"/> or <see cref="GenerateCancelMethod"/>, not both.</para></remarks>
		public string CancelMethodName
		{
			get
			{
				return cancelMethodName;
			}
			set
			{
                cancelMethodName = value;
			}
		}

        /// <summary>
        /// Gets or sets a value indicating whether to generate a cancel method.
        /// </summary>
        /// <remarks><para>By default, this property is set to <c>false</c>.  Set it to <c>true</c> only if your server supports cancellation.</para>
        /// <para>When you set <see cref="CancelMethodName"/> to any non-null value, <see cref="GenerateCancelMethod"/> is set to <c>true</c>.</para>
        /// <para>When you set <see cref="GenerateCancelMethod"/> to <c>true</c>, the name of the cancel method is set to &lt;<see cref="BaseName"/>&gt;AsyncCancel.</para>
        /// <para>Use either <see cref="CancelMethodName"/> or <see cref="GenerateCancelMethod"/>, not both.</para></remarks>
		public bool GenerateCancelMethod
		{
			get
			{
				return (cancelMethodName != null);
			}
			set
			{
				if (!value)
				{
					cancelMethodName = null;
				}
				else if (cancelMethodName == null)
				{
					cancelMethodName = string.Empty;
				}
                Debug.Assert((cancelMethodName != null) == value);
			}
		}

        /// <summary>
        /// Gets or sets the type of the callback interface for this operation.
        /// </summary>
        public Type CallbackInterface
        {
            get { return callbackInterface; }
            set { callbackInterface = value; }
        }

        private string baseName = string.Empty;
        private string startMethodName = string.Empty;
        private string completedEventName = string.Empty;
        private string outputTypeName = string.Empty;
        private string cancelMethodName = null; // By default, don't generate a Cancel method.
        private Type callbackInterface;
    }
}

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

Ron A Inbar
Software Developer (Senior) Philips Healthcare
Israel Israel
I got my B.Sc. in Mathematics and Computer Science from Tel Aviv University in 1997. Since then I have developed software in UNIX, Win32 and .NET. I currently live in Haifa.

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170915.1 | Last Updated 26 Nov 2008
Article Copyright 2008 by Ron A Inbar
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid