我有一个exe。在这个exe中。我启动一个服务,将其称为 serviceManager,然后启动另一个服务,将其称为 serviceChild。
当我使用 serviceChild 创建一个带有 serviceManager 的频道时,调用 serviceManager 的回调。它会冻结。
所有的服务绑定都是 netnamedpipebinding。
谁能告诉我发生了什么?
和我的代码: 界面:
[ServiceContract]
internal interface IChild
{
[OperationContract]
CommunicationState GetState();
}
[ServiceContract]
public interface IManager
{
[OperationContract]
CommunicationState GetState();
}
和:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
public class Child : IChild
{
private readonly Guid _address = Guid.NewGuid();
private readonly ServiceHost _host;
public Guid Address
{
get { return _address; }
}
public Child()
{
_host = new ServiceHost(this);
var binding = new NetNamedPipeBinding();
var clientAddress = Helper.GetClientAddress(_address);
_host.AddServiceEndpoint((typeof(IChild)), binding, clientAddress);
_host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
_host.AddServiceEndpoint(new UdpDiscoveryEndpoint());
_host.Open();
}
public void Open()
{
if(!Manager.IsRunning()){Manager.Start();}
var binding = new NetNamedPipeBinding();
var endpoint = new EndpointAddress(Constants.ADDRESS_PIPE_SERVER);
using (var factory = new ChannelFactory<IManager>(binding, endpoint))
{
IManager managerChannel = null;
try
{
managerChannel = factory.CreateChannel();
**managerChannel.GetState();**// BUG:<-----
}
catch (Exception ex)
{
MessageBox.Show("ex " + ex);
}
finally
{
Helper.CloseChannel((ICommunicationObject)managerChannel);
}
}
}
public CommunicationState GetState()
{
return _host.State;
}
}
管理者:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
public class Manager : IManager
{
private static ServiceHost _host;
private static Manager _instance;
private static Manager Instance
{
get { return _instance ?? (_instance = new Manager()); }
}
#region IManager Members
public CommunicationState GetState()
{
return _host.State;
}
#endregion
public static void Start()
{
if (_host != null
&& (_host.State == CommunicationState.Created
|| _host.State == CommunicationState.Opening
|| _host.State == CommunicationState.Opened))
{
return;
}
_host = new ServiceHost(Instance);
var binding = new NetNamedPipeBinding();
var endpoint = Constants.ADDRESS_PIPE_SERVER;
_host.AddServiceEndpoint((typeof (IManager)), binding, endpoint);
_host.Open();
}
public static bool IsRunning()
{
var binding = new NetNamedPipeBinding();
var endpointAddress = new EndpointAddress(Constants.ADDRESS_PIPE_SERVER);
var factory = new ChannelFactory<IManager>(binding, endpointAddress);
IManager managerChannel = null;
try
{
managerChannel = factory.CreateChannel();
// wait for server to respond
if (_host != null && _host.State == CommunicationState.Opened)
{
var contextChannel = managerChannel as IClientChannel;
if (contextChannel != null) contextChannel.OperationTimeout = TimeSpan.FromMilliseconds(1000);
}
try
{
managerChannel.GetState();
}
catch (Exception)
{
return false;
}
return true;
}
catch (EndpointNotFoundException e)
{
return false;
}
finally
{
Helper.CloseChannel((ICommunicationObject) managerChannel);
}
}
其他:
internal static class Helper
{
public static void CloseChannel(ICommunicationObject channel)
{
try
{
if (channel.State == CommunicationState.Opened) channel.Close();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
channel.Abort();
}
}
public static string GetClientAddress(object serviceAddress)
{
return string.Format(Constants.ADDRESS_PIPE_CLIENT_FORMAT, serviceAddress);
}
}
internal static class Constants
{
internal static string ADDRESS_PIPE_SERVER = @"net.pipe://localhost/Server";
internal static string ADDRESS_PIPE_CLIENT_FORMAT = @"net.pipe://localhost/Client_{0}";
}
最后,测试:
private void ActionLoaded(object sender, RoutedEventArgs e)
{
Manager.Start();
}
private void ActionConnectedSelf(object sender, RoutedEventArgs e)
{
var client = new Child();
client.Open();
}