Beta2 - CallExternalMethod vs InvokeMethod activity

The new CallExternalMethod replaces the Beta1 InvokeMethod activity I see. But a significant change is that the new one serializes all objects passed to the external method. Beta1 did not do that. I'd prefer to make that optional, allowing me to pass by reference a la Beta1. Is there any way to do this

Riley



Answer this question

Beta2 - CallExternalMethod vs InvokeMethod activity

  • MRMOU812

    Riley

    hmmm...the ICloneable wrapper idea works to an extent. I now get my external method called.

    Unfortunately, the method parameters passed across the interface seem to be regarded as part of the workflow state - even though in my case the argument is a local variable. Consequently, when the workflow idles it tries to persist my cloneable wrapper. This fails unless the object is marked as serializable.

    Regards,

    David.


  • Ash31

    Riley

    Thank you for pointing out that the Beta2 now serializes the method parameters passed to an external method. That has explained a problem I was having.

    Following your post, I've used reflector to examine the implementation of the CallExternalMethodActivity.Execute method.

    This uses a method to clone the method parameters (InvokeHelper.CloneOutboundValue(...). I notice that this method checks to see if the object implements ICloneable and if so uses the object's clone method to duplicate the object. If the object doesn't implement ICloneable then it uses BinaryFormatter to serialize and deserialize the object in order to clone it.

    This suggests that one approach to passing references is to wrap the reference in a class that implements ICloneable and who's implementation simply copies the reference to a new wrapper.

    I'll give this approach ago for my problem and see if it works. Seems a shame to have to jump through hoops though.

    Regards,


    David.


  • WaltXS

    To implement pass by ref in this case, I'm both marking as Serializable and implementing ICloneable. Seems you need your parameter object to be persisted when the WF is, so it will have to be Serializeable, right

    I'm not sure if my case maps to yours, but here's what I've found. I'm using both CallExternalMethod and HandleExternalEvent. I pass an MyObject to the first and get a MyObject back in the event args of the second. The choice of both as to whether to serialiaze or clone is similar. Mark my MyObject as ICloneable (and implementing Clone() to return 'this') for the first produces a pass by ref. Do the same for my custom EventArgs causes the second to pass by ref.

    In my case I think what I am going to do is pass by ref in CallExternalMethod, and serialize back in HandleExternalEvent. Thanks for your help

    Would love to hear what the WWF team thinks about this

    Riley


  • pspet

    Arjun,

    Yes, performance is the reason for wanting to pass by ref. My situation is that each WF running goes out to and returns from a LocalService at least 4 times (but usually the LocalService is in fact just a inproc dll). And we have a 100 or so of these WF's running on a machine. So avoiding unnecessary serialization seems like a good idea. Measurement of course will tell us how critical this is.

    Curious, why would you not recommend doing our ICloneable dance

    Riley


  • Ben Zamora

    David,

    Thanks for the helpful digging. I'm going to experiment too with ICloneable. Please update me as you learn.


    Riley


  • Mister T

    Arjun,

    In my particular case I am passing a SoapEnvelope across the external method interface. Regrettably, its not possible to clone this object through serialization or XML serialization.

    Consequently, I'm just passing it by reference in order to carry the complex data that it contains (WS-Addressing stuff in particular) into my host. I could make my own version of the object but would end up duplicating a lot of code.

    So, my scenario is something of an edge case due to limitations of WSE3.0.

    David.


  • Pantheman42

    Outgoing messages are cloned because the workflow and host should not have shared state between them. This was a known issue in Beta1 and fixed for Beta2. While the workaround mentioned sounds like it works (and is a nice little hack :-) ), it's not something I would recommend doing.

    Were you looking to pass by-ref for perf reasons, or maybe something else


  • Beta2 - CallExternalMethod vs InvokeMethod activity