/* csc /t:library Share.cs */ namespace Microshaoft { using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Serialization.Formatters; public static class RemotingHelper { public static void StartRemoting ( Type RemotingType , string Url , int Port , WellKnownObjectMode ServiceMode ) { BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary ht = new Hashtable(); ht["port"] = Port; TcpChannel tc = new TcpChannel(ht, null, provider); ChannelServices.RegisterChannel(tc, false); RemotingConfiguration.RegisterWellKnownServiceType(RemotingType, Url, ServiceMode); Console.WriteLine("Remoting Object Started ..."); } public static void StartRemoting<T> ( string Url , int Port , WellKnownObjectMode Mode ) { StartRemoting(typeof(T), Url, Port, Mode); } public static T GetRemotingLocalClientProxyObject<T> ( string Url ) { return (T) Activator.GetObject ( typeof(T) , Url ); } } } namespace Microshaoft.RemotingObjects.Share { using System; public interface IRemotingSyncInvokerAsyncHandler { void BeginSyncWaitFor(string user, string command); void SendCommand(string user, string command); } } /* csc /r:Share.dll Server.cs */ namespace Microshaoft { using System; using System.Threading; using System.Runtime.InteropServices; public class SyncInvokerAsyncHandler<TSessionData, TAsyncHandleCommand> { public delegate void AsyncEventHandler ( SyncInvokerAsyncHandler<TSessionData, TAsyncHandleCommand> sender , TAsyncHandleCommand command ); public event AsyncEventHandler AsyncHandle; private bool _waiting = false; private AutoResetEvent _are; public SyncInvokerAsyncHandler(TSessionData session) { _sessionData = session; } public void CompleteAsyncHandle() { _waiting = false; _are.Set(); if (AsyncHandle != null) { Delegate[] D = AsyncHandle.GetInvocationList(); AsyncEventHandler handler = null; foreach (Delegate d in D) { handler = (AsyncEventHandler) d; AsyncHandle -= handler; } } } public void SendCommand(TAsyncHandleCommand command) { if (AsyncHandle != null) { AsyncHandle(this, command); } } private TSessionData _sessionData; public TSessionData SessionData { get { return _sessionData; } } public void SyncInvoke(TSessionData session) { _sessionData = session; _are = new AutoResetEvent(false); _waiting = true; Wait(); } private void Wait() { while (_waiting) { Console.WriteLine("WaitOne ..."); _are.WaitOne(); } } } } namespace Microshaoft.RemotingObjects.Server { using System; using System.Runtime.InteropServices; using System.Collections.Generic; using Microshaoft; public class SyncInvokerAsyncHandlerProcessor { private Dictionary<string, SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand>> _invokers = new Dictionary<string, SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand>>(); public void SyncInvoke(string sessionID, string completeCommand) { if (!_invokers.ContainsKey(sessionID)) { UserSessionData session = new UserSessionData(); session.SessionID = sessionID; session.CompleteCommand = completeCommand; SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand> invoker = new SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand>(session); invoker.AsyncHandle += new SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand>.AsyncEventHandler(Invokers_AsyncHandle); _invokers.Add(session.SessionID, invoker); invoker.SyncInvoke(session); } } public void SendCommand(string sessionID, string commandText) { if (_invokers.ContainsKey(sessionID)) { AsyncHandleCommand command = new AsyncHandleCommand(); command.CommandText = commandText; SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand> invoker = _invokers[sessionID]; invoker.SendCommand(command); } } void Invokers_AsyncHandle(SyncInvokerAsyncHandler<UserSessionData, AsyncHandleCommand> sender, AsyncHandleCommand command) { if (sender.SessionData.CompleteCommand == command.CommandText) { sender.CompleteAsyncHandle(); _invokers.Remove(sender.SessionData.SessionID); } } } public class UserSessionData { public string SessionID; public string CompleteCommand; } //[StructLayout(LayoutKind.Sequential)] public class AsyncHandleCommand { public string CommandText; } } namespace Microshaoft.RemotingObjects.Server { using System; using System.Threading; using System.Collections; using System.ServiceProcess; using System.ComponentModel; using System.Security.Principal; using System.Configuration.Install; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using Microshaoft; using Microshaoft.Win32; using Microshaoft.RemotingObjects; public class ServiceHost : ServiceBase { public static readonly string serviceName = "RemotingSyncAsycInvokeService"; private static SyncInvokerAsyncHandlerProcessor _processor; public static SyncInvokerAsyncHandlerProcessor Processor { get { return _processor; } } static void Main(string[] args) { ServiceHost service = new ServiceHost(); int l = 0; bool needFreeConsole = false; if (args != null) { l = args.Length; } if (l > 0) { if (args[0].ToLower() == "/console") { needFreeConsole = true; NativeMethods.AllocConsole(); Console.Title = "Server ..."; Console.WriteLine("Alloc Console ..."); Console.WriteLine("Current User Identity: {0}", WindowsIdentity.GetCurrent().Name); Console.WriteLine(".Net Framework version: {0}", Environment.Version.ToString()); } Console.Title = "Server"; //不能以服务运行 Console.WriteLine("Console"); service.OnStart(null); Console.ReadLine(); return; } Console.WriteLine("Service"); ServiceBase.Run(service); if (needFreeConsole) { Console.WriteLine("Free Console ..."); NativeMethods.FreeConsole(); } } public ServiceHost() { CanPauseAndContinue = true; ServiceName = ServiceHost.serviceName; } protected override void OnStart(string[] args) { Console.WriteLine(Environment.Version.ToString()); _processor = new SyncInvokerAsyncHandlerProcessor(); RemotingHelper.StartRemoting<RemotingSyncInvokerAsyncHandler> ( "SyncInvokeAsyncHandler" , 8080 , WellKnownObjectMode.SingleCall ); Console.WriteLine("Server . , Press Enter key to exit."); } } [RunInstallerAttribute(true)] public class ProjectInstaller : Installer { private ServiceInstaller serviceInstaller; private ServiceProcessInstaller processInstaller; public ProjectInstaller() { processInstaller = new ServiceProcessInstaller(); serviceInstaller = new ServiceInstaller(); // Service will run under system account processInstaller.Account = ServiceAccount.LocalSystem; // Service will have Start Type of Manual serviceInstaller.StartType = ServiceStartMode.Manual; serviceInstaller.ServiceName = ServiceHost.serviceName; Installers.Add(serviceInstaller); Installers.Add(processInstaller); } } } namespace Microshaoft.RemotingObjects { using System; using Microshaoft; using Microshaoft.RemotingObjects.Share; using Microshaoft.RemotingObjects.Server; public class RemotingSyncInvokerAsyncHandler : MarshalByRefObject, IRemotingSyncInvokerAsyncHandler { public void BeginSyncWaitFor(string user, string completeCommand) { ServiceHost.Processor.SyncInvoke(user, completeCommand); } public void SendCommand(string user, string command) { ServiceHost.Processor.SendCommand(user, command); } } } namespace Microshaoft.Win32 { using System; using System.Runtime.InteropServices; public static class NativeMethods { [ DllImport ( "kernel32.dll" ) ] public static extern bool AllocConsole(); [ DllImport ( "kernel32.dll" ) ] public static extern bool FreeConsole(); } } /* csc /r:Share.dll Client.cs */ namespace ConsoleApplication { using System; using System.Threading; using Microshaoft; using Microshaoft.RemotingObjects.Share; public class Class1 { static void Main(string[] args) { Console.Title = "Client"; Class1 a = new Class1(); a.Run(); Console.WriteLine(Environment.Version.ToString()); Console.ReadLine(); } public void Run() { IRemotingSyncInvokerAsyncHandler _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingSyncInvokerAsyncHandler>("tcp://127.0.0.1:8080/SyncInvokeAsyncHandler"); string s; while ((s = Console.ReadLine()) != "q") { string[] a = s.Split(' '); Console.WriteLine("BeginSyncWaitFor: {0} at {1} blocking ...", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); _proxy.BeginSyncWaitFor(a[0], a[1]); Console.WriteLine("EndSyncWaitFor: {0} at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); } } } } /* csc /r:Share.dll ControlerClient.cs */ namespace ConsoleApplication { using System; using System.Threading; using Microshaoft; using Microshaoft.RemotingObjects.Share; public class Class1 { static void Main(string[] args) { Console.Title = "Controler Client"; Class1 a = new Class1(); a.Run(); Console.WriteLine(Environment.Version.ToString()); Console.ReadLine(); } public void Run() { IRemotingSyncInvokerAsyncHandler _proxy = RemotingHelper.GetRemotingLocalClientProxyObject<IRemotingSyncInvokerAsyncHandler>("tcp://127.0.0.1:8080/SyncInvokeAsyncHandler"); string s; while ((s = Console.ReadLine()) != "q") { string[] a = s.Split(' '); _proxy.SendCommand(a[0], a[1]); Console.WriteLine("SendCommand end: [{0}] at {1}", s, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")); } } } }