0

我希望从托管它的同一个 .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 代码修改为以下内容,则会在我访问服务时引发超时异常(注意:如果我在控制台应用服务主机中执行相同操作,我不会得到超时...) :

        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 跟踪不提供附加详细信息(只是确认引发了超时异常)。有什么想法吗?{这不是关于 WCF 异常管理最佳实践的问题;我正在寻找从服务主机中访问服务并被这个奇怪的超时异常阻止}

编辑:当服务主机是 WPF 应用程序(可能是其他应用程序)时,会发生此超时;但是作为服务主机的控制台应用程序的行为与我预期的一样(例如,可以访问自托管服务)。我已经更新了标题和标签以反映这个新信息......

在此先感谢,

4

2 回答 2

1

这是因为 WPF 服务主机将服务托管在与使用服务相同的线程上。问题在这里定义: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;
        }
于 2012-07-03T19:45:45.237 回答
0

我不确定你的 contract.GepProperty 做了什么(但它首先不应该是一个属性)

这按预期工作

- - 主持人 - -

  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>
于 2012-06-22T17:55:44.473 回答