|
This aspect simplifies asynchronous operations.
Note the AsyncAspect is not compatible with other type builders that generate a method body.
If you apply them along with the AsyncAspect to an abstract method, they will be igored.
AsyncAspect.cs
using System;
using System.Threading;
using NUnit.Framework;
using BLToolkit.Aspects;
using BLToolkit.Reflection;
namespace HowTo.Aspects
{
public abstract class AsyncTestObject
{
// This is a member we will call asynchronously.
//
public int Test(int intVal, string strVal)
{
Thread.Sleep(200);
return intVal;
}
// Begin async method should take the same parameter list as the Test method and return IAsyncResult.
// Two additional parameters can be provided: AsyncCallback and state object.
// 'Begin' prefix is a part of the default naming convention.
//
[Async] public abstract IAsyncResult BeginTest(int intVal, string strVal);
[Async] public abstract IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback);
[Async] public abstract IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback, object state);
// End async method should take IAsyncResult and return the same type as the Test method.
// 'End' prefix is a part of the default naming convention.
//
[Async] public abstract int EndTest (IAsyncResult asyncResult);
// Begin/End naming convention is not required. You can use any name
// if you provide the target method name as a parameter of the Async attribute.
//
[Async("Test")]
public abstract IAsyncResult AnyName(int intVal, string strVal, AsyncCallback callback, object state);
// Here we provide the parameter list along with the method name.
//
[Async("Test", typeof(int), typeof(string))]
public abstract int AnyName(IAsyncResult asyncResult);
}
[TestFixture]
public class AsyncAspectTest
{
[Test]
public void AsyncTest()
{
AsyncTestObject o = TypeAccessor<AsyncTestObject>.CreateInstance();
IAsyncResult ar = o.BeginTest(1, "10");
Assert.AreEqual(1, o.EndTest(ar));
}
private static void CallBack(IAsyncResult ar)
{
Console.WriteLine("Callback");
AsyncTestObject o = (AsyncTestObject)ar.AsyncState;
o.EndTest(ar);
}
[Test]
public void CallbackTest()
{
AsyncTestObject o = TypeAccessor<AsyncTestObject>.CreateInstance();
o.BeginTest(2, null, CallBack, o);
}
[Test]
public void AnyNameTest()
{
AsyncTestObject o = TypeAccessor<AsyncTestObject>.CreateInstance();
IAsyncResult ar = o.AnyName(2, null, null, null);
Assert.AreEqual(2, o.AnyName(ar));
}
}
} |
BLToolkit type builder will generate the following for the class above:
[BLToolkitGenerated]
internal delegate int TestObject$Test$Delegate(int, string);
[BLToolkitGenerated]
public sealed class AsyncTestObject : HowTo.Aspects.AsyncAspectTest.AsyncTestObject
{
public override IAsyncResult BeginTest(int intVal, string strVal)
{
AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult();
r.Delegate = new TestObject$Test$Delegate(base.Test);
r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, null, null);
return r;
}
public override IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback)
{
AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult();
r.Delegate = new TestObject$Test$Delegate(base.Test);
r.AsyncCallback = callback;
r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, new AsyncCallback(r.CallBack), null);
return r;
}
public override IAsyncResult BeginTest(int intVal, string strVal, AsyncCallback callback, object state)
{
AsyncAspectBuilder.InternalAsyncResult r = new AsyncAspectBuilder.InternalAsyncResult();
r.Delegate = new TestObject$Test$Delegate(base.Test);
r.AsyncCallback = callback;
r.InnerResult = r.Delegate.BeginInvoke(intVal, strVal, new AsyncCallback(r.CallBack), state);
return r;
}
public override int EndTest(IAsyncResult asyncResult)
{
AsyncAspectBuilder.InternalAsyncResult r = (AsyncAspectBuilder.InternalAsyncResult)asyncResult;
return ((TestObject$Test$Delegate)r.Delegate).EndInvoke(r.InnerResult);
}
} |
| |