Flush() public method

public Flush ( ) : void
return void
示例#1
0
        /// <summary>
        /// Überträgt ein Objekt in eine Kommunikationseinheit.
        /// </summary>
        /// <param name="pipe">Die Kommunikationseinheit.</param>
        /// <param name="serializer">Die Serialisierungsinstanz.</param>
        /// <param name="instance">Das betroffene Objekt.</param>
        internal static void SendToPipe( PipeStream pipe, XmlSerializer serializer, object instance )
        {
            // Create helper
            using (var temp = new MemoryStream())
            {
                // Create writer configuration
                var settings = new XmlWriterSettings { CheckCharacters = false };

                // Create
                using (var writer = XmlWriter.Create( temp, settings ))
                    serializer.Serialize( writer, instance );

                // Read data and create buffer for length
                var len = new byte[sizeof( long )];
                var data = temp.ToArray();

                // Lock briefly
                var lenLock = GCHandle.Alloc( len, GCHandleType.Pinned );
                try
                {
                    // Fill
                    Marshal.WriteInt64( lenLock.AddrOfPinnedObject(), data.LongLength );
                }
                finally
                {
                    // Release
                    lenLock.Free();
                }

                // Send all
                pipe.Write( len, 0, len.Length );

                // Write in blocks
                for (int n = 0; n < data.Length; )
                {
                    // Block size
                    int block = Math.Min( BlockSize, data.Length - n );

                    // Send chunck
                    pipe.Write( data, n, block );
                    pipe.Flush();

                    // Advance
                    n += block;
                }

                // Flush
                pipe.Flush();
                pipe.WaitForPipeDrain();
            }
        }
        //MAIN
        private NKRemotingProxy(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken)
        {
            this.context = context;
            this._localHandlers = null;
            this.ns = ns;

            this.cancelToken = cancelToken;
            
            var exe = System.Reflection.Assembly.GetEntryAssembly().Location;
            var path = System.IO.Path.GetDirectoryName(exe);
            ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo;
            startInfo.FileName = exe;
            startInfo.WorkingDirectory = path;
            startInfo.UseShellExecute = false;
         
            var syncPipeOut = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
            var syncPipeIn = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
            var pipeOutHandle = syncPipeOut.GetClientHandleAsString();
            var pipeInHandle = syncPipeIn.GetClientHandleAsString();

            this.syncPipeOut = syncPipeOut;
            this.syncPipeIn = syncPipeIn;
            
            startInfo.Arguments = "NKR=" + buildInitMessage(pipeOutHandle, pipeInHandle);

            this.id = id;
            process = Process.Start(startInfo);
            NKEventEmitter.global.emit<string>("NKS.ProcessAdded", id, false);
            process.EnableRaisingEvents = true;
            process.Exited += Process_Exited;
       
            var pipeName = Convert.ToBase64String(getUniqueKey());
            var asyncPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
            this.asyncPipe = asyncPipe;
            NKScriptChannel.nativeFirstSequence -= 5;

            string nativeFirstSeq = NKScriptChannel.nativeFirstSequence.ToString();
   
            var handshake = new NKRemotingMessage();
            handshake.command = NKRemotingMessage.Command.NKRemotingHandshake;
            handshake.args = new string[] { pipeName, ns, id, nativeSeqMax.ToString() };

            syncPipeOut.WriteByte(100);
            syncPipeOut.Flush();
            syncPipeOut.WaitForPipeDrain();
            syncPipeOut.DisposeLocalCopyOfClientHandle();
            syncPipeIn.DisposeLocalCopyOfClientHandle();

            writeObject(syncPipeOut, handshake);
            syncPipeOut.WaitForPipeDrain();

            var handshakeReply = readObject(syncPipeIn);
            if (handshakeReply == null || handshakeReply.command != NKRemotingMessage.Command.NKRemotingHandshake)
                Environment.Exit(911);

            asyncPipe.WaitForConnection();
            cancelToken.Register(requestClientTeardown);
            var nkready = readObject(asyncPipe);
            if (nkready == null || nkready.command != NKRemotingMessage.Command.NKRemotingReady)
               Environment.Exit(910);
     
            Task.Factory.StartNew((s)=> _processServerMessages(asyncPipe), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            NKEventEmitter.global.forward<NKEvent>(eventForwarderFromMain);

        }
示例#3
0
        protected void HandlePipeConnection(PipeStream pipeStream, IDictionary<string, object> initialMessage)
        {
            // You think we'd scope these with using() right? They are IDisposable
            //  after all... but nope, the implementation of these is such that
            //  disposing of them also disposes the underlying stream.  Leaving us
            //  with a double (or triple if we close the pipeServer stream ourselves)
            //  close.  Yay.  Instead we abandoned these to the GC knowing that they
            //  are only wrappers anyway and have/use little/no resources of their own.
            BinaryReader reader = new BinaryReader(pipeStream, Encoding.Unicode);
            BinaryWriter writer = new BinaryWriter(pipeStream, Encoding.Unicode);

            try
            {
                // If we should announce with a specific message, do so
                if (initialMessage != null)
                {
                    WriteMessage(writer, initialMessage);
                }

                // So long as our Func<> returns true, we keep going.  When it returns false,
                //  it is done and its time to closeup and look for another client.
                while (StreamAction(reader, writer)) { }
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while using pipe connection: {0}", e);
            }

            try
            {
                pipeStream.Flush();
                pipeStream.WaitForPipeDrain();
                pipeStream.Close();
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while flushing/closing pipe connection: {0}", e);
            }
        }
示例#4
0
		public static void Write(BinaryFormatter formatter, PipeStream stream, object data, bool isAsync, TimeoutHelper timeoutHelper)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}

			if (data == null)
			{
				throw new ArgumentNullException("data");
			}

			MemoryStream ms = new MemoryStream(stream.OutBufferSize * 2);

			BinaryWriter bw = new BinaryWriter(ms);
			
			try
			{
				//DateTime t = DateTime.Now;

				SerializeData(bw, formatter, data);

				//Console.WriteLine("序列化用时:" + (DateTime.Now - t).TotalMilliseconds);

				//t = DateTime.Now;

				// 先以流的输出缓冲大小为限定,进行一次写入
				// 一方面,由于通常情况下,流的输出缓冲大小应可以一次性输出大部分的消息体,因此,大部分消息体的输出不需要继续进行后面的遍历;
				// 另一方面,我们需要先把流的整个长度输出,这需要先输出消息体的一小部分,选择流中定义的输出缓冲大小是一个比较适中的选择;
				byte[] bytes = new byte[ms.Length > stream.OutBufferSize ? stream.OutBufferSize : ms.Length];
				ms.Read(bytes, 0, bytes.Length);

				PipeStreamRWHelper.Write(stream, bytes, 0, bytes.Length, isAsync, timeoutHelper);

				stream.Flush();
				int index = bytes.Length;

				// 当消息体较大时,对流的其余部分进行输出,这些输出以 maxBufferSize 为基准对消息体进行分块输出
				// 这尽可能的减少了循环的次数,进而减少了异步调用(需要使用工作线程)的开销,最终尽可能的提升了性能
				while (index < ms.Length)
				{
					bytes = new byte[ms.Length - index > maxBufferSize ? maxBufferSize : ms.Length - index];

					ms.Read(bytes, 0, bytes.Length);

					PipeStreamRWHelper.Write(stream, bytes, 0, bytes.Length, isAsync, timeoutHelper);

					stream.Flush();

					index += bytes.Length;
				}

				//Console.WriteLine("输出用时:" + (DateTime.Now - t).TotalMilliseconds);
			}
			finally
			{
				bw.Close();
			}
		}