none
WCF Concurrency & Multi Threaded Client RRS feed

  • Question

  • I have a WCF that is used by a multi threaded client for processing the number of requests parallel. Somehow it starts sharing data of two different requests/threads; I have tried to change the InstanceContextMode and ConcurrencyMode as following:

    • Default InstanceContextMode = PerSession, ConcurrencyMode = Single
    • InstanceContextMode = PerCall, ConcurrencyMode = Single
    • InstanceContextMode = PerCall, ConcurrencyMode = Multiple

    But there is no luck so far. There is no shared variables and functions which may cause of this concurrency issue. According to the MS documentation PerCall creates instance for each single call and it doesn't make any sense that how data is shared between instances when they have their own private memory stack.

    Workflow: There are three main components WCF, .Net Assembly 1 and .Net Assembly 2. There is a function named "Process" of WCF which takes a string parameter and returns the structured object based on the processing done through WCF. There is no instance variable in the WCF; everything in the function. This function does little processing on the string and convert it into the structured object then pass it to the function of Assembly 1 does some processing and then pass it to the function of Assembly 2 using the invoke method of reflection. This is the entire process which somehow mix the end result of two different concurrent calls.

    I would be really thankful if anyone can help to figure this issue out.

    Wednesday, June 21, 2017 6:57 AM

Answers

  • I have figured this issue out and the problem was in the component because of caching objects; multiple threads were using the same caching objects instead of cloning them.

    Thank you for your support.

    Friday, June 23, 2017 11:22 AM

All replies

  • hello Shahiid,

    The InstanceContextMode refers to the relationship between the service object and the channel.  This does not mean that each service object will be isolated (for example, in a separate application domain) from each other.  If there is a static property or other way of "sharing" data within an application, this will not prevent it.

    Based on what you have described, I believe you want PerCall and Multiple.  You would want PerSession if you want to have the same server object used for subsequent calls from the same client.

    In other words, my guess is there is a singleton or static that is collecting the results and thus one call is influencing another call.  My concern though is if this was the case and these were re-created or reset at the start of a process, the PerCall, Single should have taken care of this.

    Please post what you find!


    Cheers, Jeff

    Wednesday, June 21, 2017 11:04 PM
  • Thank you, Jeff for your answer. There is no static member through which data can be shared between multiple instances. I got your point that InstanceContextMode.PerCall doesnt mean that it isolate the each service object but logically, when we create an instance of a class it occupies its own memory which cannot be shared with other instances until it releases, no?

    Anyhow, I have found the problematic area but no idea how it would be fixed. Let me try to explain the scenario.

    WCF Method

    public object Process(string data)

    {

    //this calls the method of another component as following

    RuleEngine engine = new RuleEngine();

    engine.Run()

    engine.ValidationReport.Compile();

    var errors = engine.GetErrorMessages()

    return errors;

    }

    Component1: RuleEngine Method

    public object Run(object data)

    {

    //process some internal processing and then calls another component's function 

    Validator validator = new Validator();

    //This is the problematic area; because this validator.validate(data) takes a little while based on the number of records in the data. For example, when we call WCF from different clients with multiple threads on each client, then it starts associating results of the one thread to other; lets suppose, first I call this method with data "xyz" and there is a validation error "xyz:abc" and it takes some time to process this data and meanwhile another thread comes with data "dcef" and this data doesnt have any validation error but somehow the previous thread's error message "xyz:abc" is associated with "dcef" data. However, I have applied instance lock on this method but it doesnt work. When I apply static lock it works perfectly but performance degrades and deadlocks start occuring because of locking the resources.

    object errors = validator.validate(data);

    return errors;

    }

    Component2: Validator Method

    public object Validate(params)

    {

    //This method does some processing here and calls its own private method one by one and return the final result to run method of ruleengine

    }

    This is the scenario; please see if it helps you to understand the problem.
    • Edited by Shahiid Thursday, June 22, 2017 8:39 AM
    Thursday, June 22, 2017 8:38 AM
  • Hi Shahiid,

    >> this data doesnt have any validation error but somehow the previous thread's error message "xyz:abc" is associated with "dcef" data

    Could you share us the detailed implementation of Validate? Is the error of validator.validate a static member? It is confused that the second request return the error of the first request.

    In my option, the error from Validator should be isolated for different new Validator.

    In addition, I suggest you make a test with Validator in a simple application like winform by initlizing many Validator to check whether the errors will be mixed.

    Best Regards,

    Edward 


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, June 23, 2017 2:11 AM
  • I have figured this issue out and the problem was in the component because of caching objects; multiple threads were using the same caching objects instead of cloning them.

    Thank you for your support.

    Friday, June 23, 2017 11:22 AM
  • Hi Shahiid,

    I am glad your issue has been resolved. I would suggest you mark your reply as answer to close this thread, and then others who run into the same issue would find the solution easily.

    Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 29, 2017 8:05 AM