c# wcf - exception thrown when calling open() on proxy class

10,394

Solution 1

How are you using proxy? Creating new proxy object for each call. Add some code regarding how you use proxy.

Desired way of using proxy is for each call you create new proxy and dispose it once completed. You are calling proxy.open() for opened proxy that is wrong. It should be just called once.

Try using something like below in finally, as wcf does not dispose failed proxy and it piles up. Not sure it would help but give it a shot.

if (proxy.State == CommunicationState.Faulted)
{
    proxy.Abort();
}
else
{
    try
    {
        proxy.Close();
    }
    catch
    {
        proxy.Abort();
    }
}

Why to do this? http://msdn.microsoft.com/en-us/library/aa355056.aspx

Code you posted above would work but you will alway be eating exception. So handle wcf related exception in seperate catch and your generic catch with Excelion would abort then throw exception.

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

Also if you still want to use convenience of using statement then you can override dispose method in your proxy and dispose with abort method in case of wcf error.

And do not need to call .Open() as it will open when required with first call.

Solution 2

I'm assuming you're using .NET 3.5 or later. In .NET 3.5, the WCF ClientBase'1 class (base class for generated client proxies) was updated to use cached ChannelFactories/Channels. Consequently, unless you're using one of the Client use/creation strategies which disables caching (Client constructor that takes in a Binding object, or accessing one of a few certain properties before the backing channel is created), even though you're creating a new Client instance, it could very well still be using the same channel. In other words, before calling .Open(), always ensure you're checking the .Created status.

Solution 3

It definitely sounds like you've called Open() multiple times on the same object.

Share:
10,394
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I have the following problem, basically i have a WCF service which operates fine in small tests. However when i attempt a batch/load test i get an InvalidOperationException with the message when the open() method is called on the proxy class:

    "The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be modified while it is in the Opened state."

    I have searched google, but cannot find anyone else really quoting this exception message.

    I guess some further info on the service may be necessary for a diagnosis - when the service receives data through one of it's exposed methods, it basically performs some processing and routes the data to a service associated with the data (different data will result in different routing). To ensure that the service runs as quickly as possible, each cycle of receiving, processing and routing of the data is handled by a seperate thread in the threadpool. could this be a problem arising from one thread calling proxyClass.Open() whilst another is already using it? would a lock block eliminate this problem, if indeed this is the problem?

    thanks guys, - ive been workikng on this project for too long, and finally want to see the back of it - but this appears to be the last stumbling block, so any help much appreciated :-)

    =========================================================================

    thanks for highlighting that i shouldn't be using the using construct for WCF proxy classes. However the MSDN article isn't the most clearly written piece of literature ever, so one quick question: should i be using a proxy as such:

    try
    {
        client = new proxy.DataConnectorServiceClient();
        client.Open();
        //do work
        client.Close();
     }
     .................. //catch more specific exceptions
     catch(Exception e)
     {
        client.Abort();
     }