Self hosted WCF service global object appears to be newly created every time an endpoint is invoked
在遵循本教程之后,我将在Windows服务内部自行托管WCF服务。我的WCF服务包含一个我定期更新的全局对象。我想将该对象序列化为JSON,然后通过服务端点返回该JSON字符串。当我访问在服务上调用serialize方法的端点时,我得到的似乎是全局的全新实例。服务设置为
我以与教程相同的方式实例化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class MyWindowsService: ServiceBase {public ServiceHost serviceHost = null; public Service() { ServiceName ="MyService"; } public static void Main() { ServiceBase.Run(new MyWindowsService()); } protected override void OnStart(string[] args) { if (serviceHost != null) { serviceHost.Close(); } serviceHost = new ServiceHost(typeof(MyWCFService)); serviceHost.Open(); } protected override void OnStop() { if (serviceHost != null) { serviceHost.Close(); serviceHost = null; } } |
我的WCF服务如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class MyWCFService: IWCFService { private myObject = mySerializableObject; public MyWCFService() { myObject = new MySerializableObject(); myObject.Init(); } public Stream GetJSON() { MemoryStream stream = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MySerializableObject)); ser.WriteObject(stream, myObject); string jsonString = Encoding.ASCII.GetString(stream.ToArray()); byte[] resultBytes = Encoding.UTF8.GetBytes(jsonString); WebOperationContext.Current.OutgoingResponse.ContentType ="text/plain"; return new MemoryStream(resultBytes); } } |
如果我
在普通控制台应用程序中运行相同的代码可以正常工作。为什么会有差异?我对全局变量的处理不正确吗?
弄清楚了...我遇到了几个问题。
没有装饰正确的服务,因此它仍在运行中
默认的每次调用上下文-因此,每个连接上都有一个新的状态对象。
实例正确。旁注,使用实例创建ServiceHost时,可以在构造函数中或App.config中显式指定基本URI。这让我有些困惑,因为我遇到的许多示例都是在构造函数中而不是在配置中传递的。
这是我为后代工作的实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | [ServiceContract(Namespace ="http://my.super.original.namespace")] public interface IWCFService { [OperationContract, WebGet] Stream GetJSON(); } //Decorator goes on WCF service, not the Windows service [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class MyWCFService : IWCFService { private StateObject _myStateObject; public MyWCFService() { _myStateObject = new StateObject(); _myStateObject.Init(); } public Stream GetJSON() { . . . return"JSON String Here"; } } public class MyWindowsService : ServiceBase { public ServiceHost serviceHost = null; private readonly MyWcfService _wcfSingleton; public MyWindowsService() { ServiceName ="WindowsServiceNameHere"; _wcfSingleton = new MyWCFService(); } public static void Main() { ServiceBase.Run(new MyWindowsService()); } // Start the Windows service. protected override void OnStart(string[] args) { if (serviceHost != null) { serviceHost.Close(); } //load WCF Singleton Instance and open it for connections serviceHost = new ServiceHost(_wcfSingleton); serviceHost.Open(); } protected override void OnStop() { if (serviceHost != null) { serviceHost.Close(); serviceHost = null; } } } |