我希望从托管它的同一个.exe中连接到WCF服务。我在WPF应用程序中托管服务:
ServiceHost svc = new ServiceHost(typeof("Namespace.Service"));
svc.Open();
和
的配置文件 <service name="Namespace.Service" >
<endpoint address="Contract/tcp"
binding="netTcpBinding"
contract="Namespace.IContract"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9002"/>
</baseAddresses>
</host>
</service>
这允许我启动一个单独的VS实例,创建一个控制台应用程序并成功执行以下操作:
IChannelFactory<IContract> facContract = new ChannelFactory<IContract>(new NetTcpBinding());
IContract contract = facContract.CreateChannel(new EndpointAddress("net.tcp://localhost:9002/Contract/tcp"));
string x = contract.GetProperty; //returns value I would expect
但是,如果我将原始WPF ServiceHost代码修改为以下内容,则在访问服务时会引发超时异常(注意:如果我在Console App Service主机中执行相同操作,则不会出现超时。 ..):
ServiceHost svc = new ServiceHost(typeof("Namespace.Service"));
svc.Open();
IChannelFactory<IContract> facContract = new ChannelFactory<IContract>(new NetTcpBinding());
IContract contract = facContract.CreateChannel(new EndpointAddress("net.tcp://localhost:9002/Contract/tcp"));
string x = contract.GetProperty; //<-!!WCF Timeout exception thrown..
WCF跟踪不提供add'l详细信息(只是确认引发了超时异常)。有什么想法吗? {这不是关于WCF异常管理最佳实践的问题;我正在寻求从服务主机和服务主机内部访问服务。被这个好奇的超时异常阻止}
编辑: 当服务主机是WPF应用程序(可能是其他人)时,会发生此超时;但控制台应用程序作为服务主机的行为与我期望的一样(例如,可以访问自托管服务)。我已经更新了标题和标签以反映这个新信息...
提前致谢, Ť
答案 0 :(得分:1)
这是因为WPF servicehost在与使用服务相同的线程上托管服务。问题在此处定义:http://social.msdn.microsoft.com/Forums/en/wcf/thread/74bc9d15-c458-4f1f-81a0-ebded46b68c4。此处详细说明了解决方案:http://msdn.microsoft.com/en-us/library/ms752260.aspx
解决方案是在单独的线程ala上启动服务主机端点:
private void StartHostThread()
{
// Before opening host, add endpoints...
host.AddServiceEndpoint(typeof(IContract)),
new NetTcpBinding(),
"Contract/tcp"); //Assumes base address of net.tcp://localhost:9002/
//For hosting on its own thread, be sure to mark service attribute
// as UseSyncContext == false
ServiceBehaviorAttribute behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behavior.UseSynchronizationContext = false;
host.Open();
}
一旦主机在线程上打开,那么就可以在主UI线程ala上使用服务了:
EndpointAddress epoint = new EndpointAddress("net.tcp://localhost:9002/Contract/tcp");
IContract proxy = ChannelFactory<IContract>.CreateChannel(new NetTcpBinding(), epoint);
string xyz;
using (proxy as IDisposable)
{
xyz = proxy.GetProperty;
}
答案 1 :(得分:0)
我不确定你的合约.GepProperty是做什么的(但它不应该是第一个属性)
这可以按预期工作
---- ---- HOST
static void Main(string[] args)
{
var svc = new ServiceHost(typeof(Service1));
svc.Open();
IChannelFactory<IService1> facContract = new ChannelFactory<IService1>(new NetTcpBinding());
var contract = facContract.CreateChannel(new EndpointAddress("net.tcp://localhost:9002/Contract/tcp"));
var x = contract.DoWork();
}
---服务---
[ServiceContract]
public interface IService1
{
[OperationContract]
string DoWork();
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
public class Service1 : IService1
{
public string DoWork()
{
return "Hello Work.";
}
}
---配置---
<configuration>
<system.serviceModel>
<services>
<service name="HostAndClient.Service1">
<endpoint address="Contract/tcp" binding="netTcpBinding" contract="HostAndClient.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9002" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>