Accessing PerSession service simultaneously in WCF using C#

前端 未结 2 1751
無奈伤痛
無奈伤痛 2020-12-21 04:21

1.) I have a main method Processing, which takes string as an arguments and that string contains some x number of tasks.

2.) I have another method Status, which keep

相关标签:
2条回答
  • 2020-12-21 04:41

    First because you need to access service simultaneously, when service is processing the first client call(Processing), you need to change service concurrency mode to Multiple.

    Also you want to maintain each client processing status, so you need to set instance context mode to the PerSession.

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerSession)]
    

    Note

    • Default InstanceContextMode is PerSession
    • Default ConcurrencyMode is Single

    You can do following to make sure your configuration is compatible with PerSession InstanceContextMode, using this method, WCF will throw a run-time exception if necessary

    [ServiceContract(SessionMode=SessionMode.Required)]
    

    Note With InstanceContextMode.PerSession you will get different instance per each proxy that you create

    So you need only one instance of "Service1Client" per client, that you will call its Process method and also retrieve status from it.

    Also for virtual heavy processing you can use Thread.Sleep(millisecond) for test proposes only in the "Processing" method(Service-Side).

    For the client application if you want to call "Processing" method and then using the Status method to retrieve status, you need to call Process method Asynchronously.

    1.Right click on the service reference in solution-explorer and choose "Configure Service Reference" then check the "Generate asynchronous operation" and press OK.

    2.Change your client code like this

    static void Main(string[] args)
    {
        StartProcessing();
        StatusReport();
    
        Console.ReadLine();
    }
    
    static ServiceClient Client = new ServiceClient();
    private static bool Completed = false;
    
    public static void StartProcessing()
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(@"D:\t72CalculateReasonableWithdrawal_Input.xml");
        bool error = false;
    
        Client.ProcessingCompleted += Client_ProcessingCompleted;
        Client.ProcessingAsync(doc.OuterXml);
    
        Console.WriteLine("Processing...");
    }
    
    static void Client_ProcessingCompleted(object sender, ProcessingCompletedEventArgs e)
    {
        // processing is completed, retreive the return value of Processing operation
        Completed = true;
        Console.WriteLine(e.Result);
    }
    
    public static void StatusReport()
    {
        int i = 0;
        string temp;
        while (!Completed)
        {
            temp = Client.Status();
            Console.WriteLine("TotalTestScenarios;CurrentTestCase = {0}", temp);
            Thread.Sleep(500);
            i++;
        }
    }
    
    0 讨论(0)
  • 2020-12-21 04:47

    PerSession will not make your static variables not shared across object instances. The only thing that PerSession context mode does is controlling of object lifetime.

    With PerSession WCF does not destroy service object until session is over. Session can be closed explicitly by client or by timeout (default is 10 min). Every next call from client with the same session Id will be routed by WCF to existing object.

    Variables should be not static to prevent sharing across different service instances. State of variables will be maintened by WCF as long as you use InstanceContextMode.PerSession and binding that maintain session.

    public int TotalTests = 0;
    public int CurrentTest = 0;
    

    I would also add SessionMode.Required to contract to make sure that service is properly configured.

     [ServiceContract(SessionMode = SessionMode.Required )]
    
    0 讨论(0)
提交回复
热议问题