2013-02-09 5 views
0

Я пишу тестовый сервер WCF с помощью метода для добавления 2 чисел и ожидания настраиваемого количества миллисекунд.многопоточный сервер

Я написал wcf-клиент. Когда я открываю два экземпляра этого клиента - на clientA значение ожидания составляет 50 секунд, а на другом клиенте B - 0 секунд. Я ожидаю, что, когда клиент A будет работать (длительный процесс), клиент B немедленно получит ответ.

Это, однако, не работает. Я слежу за этим уроком WCF Concurrency

Почему это не работает для меня?

службы WCF

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 


namespace WCFService 
{ 
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Multiple,UseSynchronizationContext = true)] 
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Single)] 
    //[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple)] 
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] 
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,ConcurrencyMode = ConcurrencyMode.Multiple)] 
    public class WCFJobsLibrary : IWCFJobsLibrary 
    { 

     public ReturnClass AddNumbers(int FirstNumber, int SecondNumber, int Delay) //Add two numbers and wait a predefined interval 
     { 
      ReturnClass myReturnClass = new ReturnClass(-1, null, null, 0); 
      try 
      {    

       myReturnClass.ErrorCode = 1; 
       myReturnClass.Result = FirstNumber + SecondNumber; 
       System.Threading.Thread.Sleep(Delay); // Wait 
       return myReturnClass; 

      } 
      catch (Exception ex) 
      {    
       myReturnClass.ErrorCode = -1; 
       myReturnClass.ErrorMessage = ex.ToString(); 
       return myReturnClass; 
      } 

     } 

    } 
} 

WCF Клиент

try 
      { 

       radTextBoxResult.Text = ""; // Reset Result 
       ServiceReference1.WCFJobsLibraryClient Client = new ServiceReference1.WCFJobsLibraryClient(); 
       Client.Endpoint.Address = new System.ServiceModel.EndpointAddress(radTextBoxbaseAddress.Text); 
       WCFClient.ServiceReference1.ReturnClass AddNumbers_Result; 
       AddNumbers_Result = Client.AddNumbers(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxDelay.Text)); 


       if (AddNumbers_Result.ErrorCode < 0) 
       { 
        // If exception happens, it will be returned here 
        MessageBox.Show(AddNumbers_Result.ErrorCode.ToString() + " " + AddNumbers_Result.ErrorMessage + " " + AddNumbers_Result.ExMessage); 
       } 

       else 
       { 

        radTextBoxResult.Text = AddNumbers_Result.Result.ToString(); 

       } 

      } 

      catch (Exception ex) 
      { 

       MessageBox.Show(ex.Message.ToString()); 

      } 

App.Config

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <behaviors> 
      <serviceBehaviors> 
       <behavior name=""> 
        <serviceMetadata httpGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="false" /> 
        <serviceThrottling maxConcurrentCalls="16" maxConcurrentInstances="2147483647" maxConcurrentSessions="10" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     <services> 
      <service name="WCFService.WCFJobsLibrary"> 
       <endpoint address="" binding="wsHttpBinding" contract="WCFService.IWCFJobsLibrary"> 
        <identity> 
         <dns value="localhost" /> 
        </identity> 
       </endpoint> 
       <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
       <host> 
        <baseAddresses> 
         <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFService/WCFJobsLibrary/" /> 
        </baseAddresses> 
       </host> 
      </service> 
     </services> 
    </system.serviceModel> 
</configuration> 
+1

"Это, однако, не работает." Что происходит и что ожидается? – usr

+0

Я ожидаю, что если значение Delay для клиента A составляет 50 секунд, и я нажимаю кнопку, чтобы добавить два числа. Затем, пока он запускается, я запускаю ClientB с задержкой в ​​1 секунду и нажимаю кнопку, чтобы добавить номера буксировки, чтобы получить результат через одну секунду. что на самом деле происходит, так это то, что он не получает результат, пока ClientA не получит свой результат. – user1438082

+1

Начните 100 звонков на 50-секундную версию задержки. Разбейте отладчик на сервере. Где большинство потоков остановлено? Поместите стек. – usr

ответ

0

проблема заключалась в том, что я запускал сервис в приложении winform на основной теме. Вам нужно запустить WCF в отдельном потоке, как показано ниже.

C# Код

private void radButtonStartWCFService_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     Thread Trd = new Thread(() => StartWCFServer()); 
     Trd.IsBackground = true; 
     Trd.Start(); 

     radButtonStartWCFService.Enabled = false; 
     radButtonStartWCFService.Text = "WCF Server Started"; 

    } 

    catch(Exception ex) 
    { 
     MessageBox.Show(ex.Message.ToString()); 
    } 
} 


private void StartWCFServer() 
{ 

    try 
    { 
     sHost = new ServiceHost(typeof(WCFService.WCFJobsLibrary)); 
     sHost.Open(); 

    } 

    catch (Exception ex) 
    { 

     MessageBox.Show(ex.Message.ToString()); 

    } 
} 
1

Проблема может быть параметром InstanceContextMode = InstanceContextMode.PerSession, поскольку ваши 2 вызова используют один и тот же сеанс. Попробуйте InstanceContextMode = InstanceContextMode.PerCall.

Оба вызова, использующие один экземпляр вашего сервиса, но если первый останавливает его в течение 50 секунд, то обработка второго вызова будет ждать, пока поток не вернется в бизнес и не выполнит первый вызов.

+0

tx, но я понял - плохо поставил ответ ниже – user1438082

Смежные вопросы