How to serialize anonymous delegates

20 ביוני 2008

תגיות: ,
תגובה אחת

Few days ago we faced an interesting challenge, we needed to implement a component which can move some code execution from a web context to a different context (like a service host in a windows service).

The request first came up when we needed to perform a heavy processing work which started in a web context. Furthermore, we had some additional constraints like: This process shouldn’t use the same web application thread pool and we needed it will execute in a high isolation level. We chose to implement it with anonymous delegate and serialization. When we want to perform an operation in a web context, we’ll send our request to a lower layer which serializes the request in web context and store it in some kind of storage (database or file). Then in a “batch processing” context (which execute asynchronously) we’ll retrieve the request, deserialize and execute it.

You can download the entire example from here

(1) We prefer to hide this logic from the web layer, therefore, in web context we should call to a lower layer in my example the web page (CustomerPage.aspx) will call to CustomerBL:


protected void CalculateOrders_Click(object sender, EventArgs e)
{
CustomerBL customerBL
= new CustomerBL();
customerBL.DoSomeOperation();
}

(2) In my CustomerBL we’ll use a generic utility to request a batch processing. The API is using an anonymous delegate (in this example we’ll use the Action<> method) :


protected void CalculateOrders_Click(object sender, EventArgs e)
{
CustomerBL customerBL
= new CustomerBL();
customerBL.DoSomeOperation();
}

(3) In RequestProcess method we’ll serialize the request and store it into some storage (in our example it’ll be a file). The FileStorage class is just implementing the storing/retrieving operations from a file. This was the last operation in web context.


protected void CalculateOrders_Click(object sender, EventArgs e)
{
CustomerBL customerBL
= new CustomerBL();
customerBL.DoSomeOperation();
}

(4) Now we’ll see the asynchronous process. In our batch service we’ll retrieve the request from the file, deserialize it. Our last step is to use some reflection magic to restore the original anonymous delegate and to invoke it.


public class BatchProcess
{
public void StartProcessing()
{
string serializationResult =
FileStorage.GetInstance().ReadAllText();
object obj = Serializer.Deserialize(serializationResult);
InvokeProcess(obj);
}

private void InvokeProcess(object deserializeObject)
{
Type parameterType
=
Type.GetType(deserializeObject.GetType()
.GetGenericArguments()[
0].AssemblyQualifiedName);

Type funcType = typeof(Action<>)
.MakeGenericType(
new Type[]
{ parameterType });

// Create the original Action<T> delegate
// the first parameter is the generic parameter
// the second parameter is the Target
Delegate func = Delegate.CreateDelegate(funcType,
deserializeObject.GetType()
.GetProperties()[
1].GetValue(deserializeObject,
null), deserializeObject.GetType()
.GetProperties()[
0]
.GetValue(deserializeObject,
null) as MethodInfo);

object proxy = Activator.CreateInstance(parameterType);

// Invoke the anonymous delegate
func.DynamicInvoke(proxy);
}
}


The serialization of Func<> is very similar to its relative Action<> you just need to create appropriate Generic Func<,> with the relevant return type.

For example, if we have this anonymous delegate: Func<HeavyProcessBL, bool>, we should retrieve this two parameters and to create the original Func<> like in the example below:


Type funcType = typeof(Func<,>).MakeGenericType(new Type[] { parameterType, returnType});

Summary:

We saw how we can serialize a simple anonymous delegate (Action<>), deserialize and invoke it. It’s important to know that the anonymous delegate serialization depends on class create the anonymous delegate (CustomerBL in our example). Therefore, both of the sides (web & batch process) must have a reference to it. In order to pass some parameters they should be serializable.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

תגובה אחת

  1. Niks6 באוקטובר 2008 ב 9:14

    hii, i like the article you wrote. i also wrote an article on Serialization here : http://kaniks.blogspot.com
    feel free to post your comments

    thanks
    cheers

    להגיב