2012-03-12 116 views
0

这是我遇到的问题,我完全无能为力。我已经定义了一个IWorkerServiceContract类,如下所示:服务代理冻结应用程序

[ServiceContract] 
public interface IWorkerServiceContract 
{ 
    [OperationContract] 
    int Test(int test); 
} 

没什么特别的,我只是想测试连通性。这里是我的服务类:

class WorkerService : IWorkerServiceContract 
{ 
    public static ILogger Logger { get; set; } 

    public int Test(int test) 
    { 
     return test + 1; 
    } 

    public static ServiceHost Listen(Uri baseAddress) 
    { 
     ServiceHost host = new ServiceHost(typeof(WorkerService), baseAddress); 

     try 
     { 
      host.Open(); 
      Logger.WriteLine("Listening at address: " + baseAddress.ToString()); 
     } 

     catch (Exception e) 
     { 
      Logger.WriteLine("An exception was thrown, reason: {0}", e.Message); 
     } 

     return host; 
    } 
} 

的Logger对象由初始化类实例化,它基本上记录到()与AllocConsole分配的控制台。当我调用Listen()时,一切正常,我可以通过WCF测试客户端连接并远程调用Test()方法。虽然,当我定义代理:

public partial class WorkerProxy : ClientBase<IWorkerServiceContract>,    
            IWorkerServiceContract 
{ 
    public WorkerProxy(EndpointAddress remoteAddress) : 
     base("workerEndpoint", remoteAddress) 
    { } 

    public WorkerProxy(Uri remoteAddress) : 
     base("workerEndpoint", new EndpointAddress(remoteAddress)) 
    { } 

    public WorkerProxy(string remoteAddress) : 
     base("workerEndpoint", new EndpointAddress(remoteAddress)) 
    { } 

    public int Test(int test) 
    { 
     return base.Channel.Test(test); 
    } 
} 

,并使用下面的代码:

WorkerService.Listen("net.tcp://localhost:19000/dcalc"); 
WorkerProxy wp = new WorkerProxy("net.tcp://localhost:19000/dcalc"); 
wp.Test(0); 

申请冻结!这是我的app.config文件:

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding messageEncoding="Mtom" maxReceivedMessageSize="10485760"> 
      <readerQuotas maxArrayLength="10485760" /> 
     </binding> 
     </wsHttpBinding> 
     <netTcpBinding> 
     <binding maxReceivedMessageSize="10485760"> 
      <readerQuotas maxArrayLength="10485760" /> 
     </binding> 
     </netTcpBinding> 
    </bindings> 
    <services> 
     <service name="DCalc.Manager.ManagerService" behaviorConfiguration="managerServiceBehavior"> 
     <endpoint address="" binding="wsHttpBinding" contract="DCalc.Common.IManagerServiceContract"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
     </service> 
     <service name="DCalc.Worker.WorkerService" behaviorConfiguration="workerServiceBehavior"> 
     <endpoint address="" binding="netTcpBinding" contract="DCalc.Common.IWorkerServiceContract"/> 
     <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/> 
     </service> 
    </services> 
    <client> 
     <endpoint address="" binding="netTcpBinding" contract="DCalc.Common.IWorkerServiceContract" name="workerEndpoint" /> 
     <endpoint address="" binding="wsHttpBinding" contract="DCalc.Common.IManagerServiceContract" name="managerEndpoint" /> 
    </client> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="managerServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     <behavior name="workerServiceBehavior"> 
      <serviceMetadata policyVersion="Policy15"/> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
</configuration> 

我不明白的是,你可以看到,我已经定义了一个ManagerService,应用程序可以连接到它没有任何问题。它似乎不是一个协议问题,我得到了与wsHttpBinding相同的结果。

我在做什么错?

回答

2

由于线程死锁,您看到您的应用程序的原因被冻结,这意味着当执行一部分代码/访问公共资源时,两个线程互相锁定。

在这种情况下:

在客户端,当工人代理线程调用Test(0),它会等待响应回来。

在“服务器端”,服务器线程同时尝试控制并返回结果。由于两个线程之间存在线程关联,服务器线程将等待工作线程完成,但工作线程正在等待响应,因此它们都不能继续,并且发生死锁。

+0

谢谢,我完全忽略了这个问题!我可以连接到ManagerService,因为我制作了一个在单独的线程上运行的异步代理。 – silverhx 2012-03-13 11:43:25