You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/28 09:07:06 UTC

ignite git commit: Refactored detach logic (2).

Repository: ignite
Updated Branches:
  refs/heads/ignite-1282-detach 46107ffbe -> ca2cdff35


Refactored detach logic (2).


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ca2cdff3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ca2cdff3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ca2cdff3

Branch: refs/heads/ignite-1282-detach
Commit: ca2cdff356567631e4f6a2004c8aeedf60a8ce9f
Parents: 46107ff
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Sep 28 10:07:46 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 28 10:07:46 2015 +0300

----------------------------------------------------------------------
 .../Impl/Cache/CacheEntryFilterHolder.cs        |   3 +-
 .../Impl/Cache/CacheEntryProcessorHolder.cs     |   5 +-
 .../Impl/Cache/Store/CacheStore.cs              |   6 +-
 .../Impl/Common/PortableResultWrapper.cs        |   3 +-
 .../Impl/Compute/Closure/ComputeActionJob.cs    |   3 +-
 .../Impl/Compute/Closure/ComputeFuncJob.cs      |   7 +-
 .../Impl/Compute/Closure/ComputeOutFuncJob.cs   |   3 +-
 .../Impl/Compute/ComputeFunc.cs                 |   3 +-
 .../Impl/Compute/ComputeJob.cs                  |   3 +-
 .../Impl/Compute/ComputeJobHolder.cs            |   3 +-
 .../Impl/Compute/ComputeOutFunc.cs              |   3 +-
 .../Impl/Messaging/MessageFilterHolder.cs       |   3 +-
 .../PortableOrSerializableObjectHolder.cs       |   4 +-
 .../Impl/Portable/PortableWriterImpl.cs         | 290 +++++++++----------
 .../Impl/Portable/SerializableObjectHolder.cs   |   4 +-
 15 files changed, 152 insertions(+), 191 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryFilterHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryFilterHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryFilterHolder.cs
index 1181645..9364b34 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryFilterHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryFilterHolder.cs
@@ -92,8 +92,7 @@ namespace Apache.Ignite.Core.Impl.Cache
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _pred);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _pred));
             
             writer0.WriteBoolean(_keepPortable);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryProcessorHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryProcessorHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryProcessorHolder.cs
index 4ec1e1e..4d625c2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryProcessorHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/CacheEntryProcessorHolder.cs
@@ -105,9 +105,8 @@ namespace Apache.Ignite.Core.Impl.Cache
         {
             var writer0 = (PortableWriterImpl) writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _proc);
-            PortableUtils.WritePortableOrSerializable(writer0, _arg);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _proc));
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _arg));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
index 3fbc705..5bdb8a1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Store/CacheStore.cs
@@ -17,6 +17,7 @@
 
 namespace Apache.Ignite.Core.Impl.Cache.Store
 {
+    using System;
     using System.Collections;
     using System.Diagnostics;
     using Apache.Ignite.Core.Cache.Store;
@@ -242,8 +243,9 @@ namespace Apache.Ignite.Core.Impl.Cache.Store
                 {
                     foreach (var obj in objects)
                     {
-                        writer.DetachNext();
-                        writer.WriteObject(obj);
+                        var obj0 = obj;
+
+                        writer.WithDetach(w => w.WriteObject(obj0));
                     }
                 }
                 finally

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PortableResultWrapper.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PortableResultWrapper.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PortableResultWrapper.cs
index 733bed0..71d842f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PortableResultWrapper.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Common/PortableResultWrapper.cs
@@ -61,8 +61,7 @@ namespace Apache.Ignite.Core.Impl.Common
         {
             var writer0 = (PortableWriterImpl) writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, Result);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, Result));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeActionJob.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeActionJob.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeActionJob.cs
index c91a167..58f8739 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeActionJob.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeActionJob.cs
@@ -65,8 +65,7 @@ namespace Apache.Ignite.Core.Impl.Compute.Closure
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _action);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _action));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeFuncJob.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeFuncJob.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeFuncJob.cs
index 381c701..d778632 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeFuncJob.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeFuncJob.cs
@@ -67,11 +67,8 @@ namespace Apache.Ignite.Core.Impl.Compute.Closure
         {
             PortableWriterImpl writer0 = (PortableWriterImpl) writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _clo);
-
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _arg);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _clo));
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _arg));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeOutFuncJob.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeOutFuncJob.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeOutFuncJob.cs
index 5f719cd..b3adcc4 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeOutFuncJob.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/Closure/ComputeOutFuncJob.cs
@@ -62,8 +62,7 @@ namespace Apache.Ignite.Core.Impl.Compute.Closure
         {
             var writer0 = (PortableWriterImpl) writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _clo);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _clo));
         }
 
         public ComputeOutFuncJob(IPortableReader reader)

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeFunc.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeFunc.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeFunc.cs
index a971418..e827136 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeFunc.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeFunc.cs
@@ -75,8 +75,7 @@ namespace Apache.Ignite.Core.Impl.Compute
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _func);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _func));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJob.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJob.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJob.cs
index f4ed999..c3c787f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJob.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJob.cs
@@ -104,8 +104,7 @@ namespace Apache.Ignite.Core.Impl.Compute
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, Job);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, Job));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
index a0de895..91bf8ed 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
@@ -220,8 +220,7 @@ namespace Apache.Ignite.Core.Impl.Compute
         {
             PortableWriterImpl writer0 = (PortableWriterImpl) writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _job);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _job));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeOutFunc.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeOutFunc.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeOutFunc.cs
index dda04b6..b450b37 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeOutFunc.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeOutFunc.cs
@@ -79,8 +79,7 @@ namespace Apache.Ignite.Core.Impl.Compute
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, _func);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, _func));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
index 21c66bf..9673fa5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Messaging/MessageFilterHolder.cs
@@ -155,8 +155,7 @@ namespace Apache.Ignite.Core.Impl.Messaging
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-            PortableUtils.WritePortableOrSerializable(writer0, Filter);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, Filter));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableOrSerializableObjectHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableOrSerializableObjectHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableOrSerializableObjectHolder.cs
index 06ccf8b..2d6afff 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableOrSerializableObjectHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableOrSerializableObjectHolder.cs
@@ -49,9 +49,7 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-
-            PortableUtils.WritePortableOrSerializable(writer0, Item);
+            writer0.WithDetach(w => PortableUtils.WritePortableOrSerializable(w, Item));
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
index c44a0a4..3f42db8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -57,18 +57,12 @@ namespace Apache.Ignite.Core.Impl.Portable
 
         /** Current metadata handler. */
         private IPortableMetadataHandler _curMetaHnd;
-
-        /** Current raw flag. */
-        private bool _curRaw;
-
+        
         /** Current raw position. */
         private long _curRawPos;
-
-        /** Ignore handles flag. */
-        private bool _detach;
-
-        /** Object started ignore mode. */
-        private bool _detachMode;
+        
+        /** Whether we are currently detaching an object. */
+        private bool _detaching;
 
         /// <summary>
         /// Gets the marshaller.
@@ -718,11 +712,8 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// </returns>
         public IPortableRawWriter RawWriter()
         {
-            if (!_curRaw)
-            {
-                _curRaw = true;
+            if (_curRawPos == 0)
                 _curRawPos = _stream.Position;
-            }
 
             return this;
         }
@@ -769,183 +760,142 @@ namespace Apache.Ignite.Core.Impl.Portable
         [SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
         internal void Write<T>(T obj, object handler)
         {
-            // Apply detach mode if needed.
-            PortableHandleDictionary<object, long> oldHnds = null;
-
-            bool resetDetach = false;
-
-            if (_detach)
+            // Write null.
+            if (obj == null)
             {
-                _detach = false;
-                _detachMode = true;
-                resetDetach = true;
-
-                oldHnds = _hnds;
+                _stream.WriteByte(PortableUtils.HdrNull);
 
-                _hnds = null;
+                return;
             }
 
-            try
+            if (_builder != null)
             {
-                // Write null.
-                if (obj == null)
+                // Special case for portable object during build.
+                PortableUserObject portObj = obj as PortableUserObject;
+
+                if (portObj != null)
                 {
-                    _stream.WriteByte(PortableUtils.HdrNull);
+                    if (!WriteHandle(_stream.Position, portObj))
+                        _builder.ProcessPortable(_stream, portObj);
 
                     return;
                 }
 
-                if (_builder != null)
-                {
-                    // Special case for portable object during build.
-                    PortableUserObject portObj = obj as PortableUserObject;
-
-                    if (portObj != null)
-                    {
-                        if (!WriteHandle(_stream.Position, portObj))
-                            _builder.ProcessPortable(_stream, portObj);
-
-                        return;
-                    }
-
-                    // Special case for builder during build.
-                    PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
+                // Special case for builder during build.
+                PortableBuilderImpl portBuilder = obj as PortableBuilderImpl;
 
-                    if (portBuilder != null)
-                    {
-                        if (!WriteHandle(_stream.Position, portBuilder))
-                            _builder.ProcessBuilder(_stream, portBuilder);
-
-                        return;
-                    }
-                }                
+                if (portBuilder != null)
+                {
+                    if (!WriteHandle(_stream.Position, portBuilder))
+                        _builder.ProcessBuilder(_stream, portBuilder);
 
-                // Try writting as well-known type.
-                if (InvokeHandler(handler, handler as PortableSystemWriteDelegate, obj))
                     return;
+                }
+            }
 
-                Type type = obj.GetType();
+            // Try writting as well-known type.
+            if (InvokeHandler(handler, handler as PortableSystemWriteDelegate, obj))
+                return;
 
-                IPortableTypeDescriptor desc = _marsh.Descriptor(type);
+            Type type = obj.GetType();
 
-                object typedHandler;
-                PortableSystemWriteDelegate untypedHandler;
+            IPortableTypeDescriptor desc = _marsh.Descriptor(type);
 
-                if (desc == null)
-                {
-                    typedHandler = null;
-                    untypedHandler = PortableSystemHandlers.WriteHandler(type);
-                }
-                else
-                {
-                    typedHandler = desc.TypedHandler;
-                    untypedHandler = desc.UntypedHandler;
-                }
+            object typedHandler;
+            PortableSystemWriteDelegate untypedHandler;
 
-                if (InvokeHandler(typedHandler, untypedHandler, obj))
-                    return;
-
-                if (desc == null)
-                {
-                    if (!type.IsSerializable)
-                        // If neither handler, nor descriptor exist, and not serializable, this is an exception.
-                        throw new PortableException("Unsupported object type [type=" + type +
-                            ", object=" + obj + ']');
+            if (desc == null)
+            {
+                typedHandler = null;
+                untypedHandler = PortableSystemHandlers.WriteHandler(type);
+            }
+            else
+            {
+                typedHandler = desc.TypedHandler;
+                untypedHandler = desc.UntypedHandler;
+            }
 
-                    Write(new SerializableObjectHolder(obj));
+            if (InvokeHandler(typedHandler, untypedHandler, obj))
+                return;
 
-                    return;
-                }
+            if (desc == null)
+            {
+                if (!type.IsSerializable)
+                    // If neither handler, nor descriptor exist, and not serializable, this is an exception.
+                    throw new PortableException("Unsupported object type [type=" + type +
+                        ", object=" + obj + ']');
 
-                int pos = _stream.Position;
+                Write(new SerializableObjectHolder(obj));
 
-                // Dealing with handles.
-                if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
-                    return;
+                return;
+            }
 
-                // Write header.
-                _stream.WriteByte(PortableUtils.HdrFull);
+            int pos = _stream.Position;
 
-                _stream.WriteBool(desc.UserType);
-                _stream.WriteInt(desc.TypeId);
-                _stream.WriteInt(obj.GetHashCode());
+            // Dealing with handles.
+            if (!(desc.Serializer is IPortableSystemTypeSerializer) && WriteHandle(pos, obj))
+                return;
 
-                // Skip length as it is not known in the first place.
-                _stream.Seek(8, SeekOrigin.Current);
+            // Write header.
+            _stream.WriteByte(PortableUtils.HdrFull);
 
-                // Preserve old frame.
-                int oldTypeId = _curTypeId;
-                IPortableNameMapper oldConverter = _curConverter;
-                IPortableIdMapper oldMapper = _curMapper;
-                IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
-                bool oldRaw = _curRaw;
-                long oldRawPos = _curRawPos;
+            _stream.WriteBool(desc.UserType);
+            _stream.WriteInt(desc.TypeId);
+            _stream.WriteInt(obj.GetHashCode());
 
-                // Push new frame.
-                _curTypeId = desc.TypeId;
-                _curConverter = desc.NameConverter;
-                _curMapper = desc.Mapper;
-                _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
-                _curRaw = false;
-                _curRawPos = 0;
+            // Skip length as it is not known in the first place.
+            _stream.Seek(8, SeekOrigin.Current);
 
-                // Write object fields.
-                desc.Serializer.WritePortable(obj, this);
+            // Preserve old frame.
+            int oldTypeId = _curTypeId;
+            IPortableNameMapper oldConverter = _curConverter;
+            IPortableIdMapper oldMapper = _curMapper;
+            IPortableMetadataHandler oldMetaHnd = _curMetaHnd;
+            long oldRawPos = _curRawPos;
 
-                // Calculate and write length.
-                int retPos = _stream.Position;
+            // Push new frame.
+            _curTypeId = desc.TypeId;
+            _curConverter = desc.NameConverter;
+            _curMapper = desc.Mapper;
+            _curMetaHnd = desc.MetadataEnabled ? _marsh.MetadataHandler(desc) : null;
+            _curRawPos = 0;
 
-                _stream.Seek(pos + 10, SeekOrigin.Begin);
+            // Write object fields.
+            desc.Serializer.WritePortable(obj, this);
 
-                int len = retPos - pos;
+            // Calculate and write length.
+            int retPos = _stream.Position;
 
-                _stream.WriteInt(len);
+            _stream.Seek(pos + 10, SeekOrigin.Begin);
 
-                if (_curRawPos != 0)
-                    // When set, it is difference between object head and raw position.
-                    _stream.WriteInt((int)(_curRawPos - pos));
-                else
-                    // When no set, it is equal to object length.
-                    _stream.WriteInt(len);
+            int len = retPos - pos;
 
-                _stream.Seek(retPos, SeekOrigin.Begin);
+            _stream.WriteInt(len);
 
-                // 13. Collect metadata.
-                if (_curMetaHnd != null)
-                {
-                    IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
+            if (_curRawPos != 0)
+                // When set, it is difference between object head and raw position.
+                _stream.WriteInt((int)(_curRawPos - pos));
+            else
+                // When no set, it is equal to object length.
+                _stream.WriteInt(len);
 
-                    if (meta != null)
-                        SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
-                }
+            _stream.Seek(retPos, SeekOrigin.Begin);
 
-                // Restore old frame.
-                _curTypeId = oldTypeId;
-                _curConverter = oldConverter;
-                _curMapper = oldMapper;
-                _curMetaHnd = oldMetaHnd;
-                _curRaw = oldRaw;
-                _curRawPos = oldRawPos;
-            }
-            finally
+            // 13. Collect metadata.
+            if (_curMetaHnd != null)
             {
-                // Restore handles if needed.
-                if (resetDetach)
-                {
-                    // Add newly recorded handles without overriding already existing ones.
-                    if (_hnds != null)
-                    {
-                        if (oldHnds == null)
-                            oldHnds = _hnds;
-                        else
-                            oldHnds.Merge(_hnds);
-                    }
+                IDictionary<string, int> meta = _curMetaHnd.OnObjectWriteFinished();
 
-                    _hnds = oldHnds;
-
-                    _detachMode = false;
-                }
+                if (meta != null)
+                    SaveMetadata(_curTypeId, desc.TypeName, desc.AffinityKeyFieldName, meta);
             }
+
+            // Restore old frame.
+            _curTypeId = oldTypeId;
+            _curConverter = oldConverter;
+            _curMapper = oldMapper;
+            _curMetaHnd = oldMetaHnd;
+            _curRawPos = oldRawPos;
         }
 
         /// <summary>
@@ -1104,14 +1054,40 @@ namespace Apache.Ignite.Core.Impl.Portable
 
             WriteFieldLength(_stream, pos);
         }
-
+        
         /// <summary>
-        /// Enable detach mode for the next object.
+        /// Perform action with detached semantics.
         /// </summary>
-        internal void DetachNext()
+        /// <param name="a"></param>
+        internal void WithDetach(Action<PortableWriterImpl> a)
         {
-            if (!_detachMode)
-                _detach = true;
+            if (_detaching)
+                a(this);
+            else
+            {
+                _detaching = true;
+
+                PortableHandleDictionary<object, long> oldHnds = _hnds;
+                _hnds = null;
+
+                try
+                {
+                    a(this);
+                }
+                finally
+                {
+                    _detaching = false;
+
+                    if (oldHnds != null)
+                    {
+                        // Merge newly recorded handles with old ones and restore old on the stack.
+                        // Otherwise we can use current handles right away.
+                        oldHnds.Merge(_hnds);
+
+                        _hnds = oldHnds;
+                    }
+                }
+            }
         }
 
         /// <summary>
@@ -1261,7 +1237,7 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// </summary>
         private void CheckNotRaw()
         {
-            if (_curRaw)
+            if (_curRawPos != 0)
                 throw new PortableException("Cannot write named fields after raw data is written.");
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ca2cdff3/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
index a3a9fe7..404376a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/SerializableObjectHolder.cs
@@ -49,9 +49,7 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             var writer0 = (PortableWriterImpl)writer.RawWriter();
 
-            writer0.DetachNext();
-
-            PortableUtils.WriteSerializable(writer0, Item);
+            writer0.WithDetach(w => PortableUtils.WriteSerializable(w, Item));
         }
 
         /// <summary>