2012-01-30 70 views
3

我是.net的新手,對WCF知之甚少,所以如果遇到任何愚蠢的問題,請耐心等待。我想知道如果我的代碼沒有顯式產生任何線程,WCF如何在SELF-HOST場景中處理同時調用。所以在閱讀了很多關於stackoverflow之後,我創建了一個測試應用程序,但它似乎無法正常工作。請指教。非常感謝。WCF中的同時呼叫處理

請注意...

  1. 我的問題是隻有約WCF SELF HOSTING,所以請不要參考有關的任何IIS。我使用webHttpBinding
  2. 我知道有maxConnection和服務限制設置,但我只對我的研究設置中的2同時調用感興趣。所以不應該有最大的連接或線程池問題。
  3. 我的測試服務是不是使用會話。

代碼如下...

namespace myApp 
{ 
    [ServiceContract(SessionMode = SessionMode.NotAllowed)] 
    public interface ITestService 
    { 
    [OperationContract] 
    [WebGet(UriTemplate="test?id={id}")] 
    string Test(int id); 
    } 

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
        ConcurrencyMode = ConcurrencyMode.Multiple)] 
    public class TestService : ITestService 
    { 
    private static ManualResetEvent done = new ManualResetEvent(false); 

    public string Test(int id) 
    { 
     if (id == 1) 
     { 
     done.Reset(); 
     done.WaitOne(); 
     } 
     else 
     { 
     done.Set(); 
     } 
    } 
    } 
} 

的app.config ...

<system.serviceModel> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name = "TestEndpointBehavior"> 
      <webHttp/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <services> 
     <service name = "myApp.TestService"> 
     <endpoint address = "" behaviorConfiguration="TestEndpointBehavior" 
        binding = "webHttpBinding" 
        contract = "myApp.ITestService"> 
     </endpoint> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:8080/test/"/> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    </system.serviceModel> 
    <system.web> 
    <sessionState mode = "Off" /> 
    </system.web> 

我如何測試...

一旦有應用程序的運行,我打開我的瀏覽器在FF的情況下,打了一個電話給http:// localhost:8080/test/test?id = 1。此請求讓應用暫停等待信號,即WaitOne。然後在另一個瀏覽器選項卡中撥打另一個電話http:// localhost:8080/test/test?id = 2。期望的是,這個請求將設置信號,因此服務器將返回這兩個請求。

但是我看到應用程序掛起並且第二次請求沒有輸入測試功能。所以顯然我的代碼不支持同時/併發調用。哪裏不對了?

+1

您是否嘗試過在調試器中設置斷點? – 2012-01-30 18:53:10

+0

WCF Services是無狀態的,至少它們應該是。這會讓我相信每個調用都有一個單獨的'ManualResetEvent'。 – cadrell0 2012-01-30 19:00:35

+0

@ cadrell0這個人'私人靜態ManualResetEvent done'具有AppDomain的範圍。它在線程和上下文之間共享。 WCF可以以無狀態和有狀態的方式工作。 [會話,實例化和併發](http://msdn.microsoft.com/en-us/library/ms731193.aspx) – oleksii 2012-01-31 19:33:13

回答

0

您可以使用單個類來設置您的wcf服務和丟棄接口。您還需要添加global.asax文件。在你打完第二個電話後,他們全部都會返回「完成」。

此配置可以做你想做的。 創建TestService.cs:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
      ConcurrencyMode = ConcurrencyMode.Multiple)] 
[ServiceContract(SessionMode = SessionMode.NotAllowed)] 
public class TestService 
{ 
    private static ManualResetEvent done = new ManualResetEvent(false); 

    [OperationContract] 
    [WebGet(UriTemplate = "test?id={id}")] 
    public string Test(int id) 
    { 
     if (id == 1) 
     { 
      done.Reset(); 
      done.WaitOne(); 
     } 
     else 
     { 
      done.Set(); 
     } 
     return "finished"; 
    } 


} 

的web.config:

<configuration> 
<system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
</system.web> 
<system.webServer> 
<modules runAllManagedModulesForAllRequests="true" /> 
</system.webServer> 
<system.serviceModel> 
<standardEndpoints> 
<webHttpEndpoint> 
    <!-- 
     Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
     via the attributes on the <standardEndpoint> element below 
    --> 
<standardEndpoint name="" helpEnabled="false" > </standardEndpoint> 


    </webHttpEndpoint> 
</standardEndpoints> 
<behaviors> 
    <serviceBehaviors> 
    <behavior> 

     <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
     <serviceMetadata httpGetEnabled="true" /> 
     <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
     <serviceDebug includeExceptionDetailInFaults="false" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
</system.serviceModel> 
</configuration> 

Global.asax文件:

public class Global : System.Web.HttpApplication 
{ 

    protected void Application_Start(object sender, EventArgs e) 
    { 
     RouteTable.Routes.Add(new ServiceRoute("testservice", new WebServiceHostFactory(), typeof(TestService))); 
    } 
}