Solved

Simple call to Web Service results in OutOfMemoryException

Posted on 2014-01-14
8
1,601 Views
Last Modified: 2014-01-16
Hi Experts,

I have a very simple Windows Mobile 6.0 application that polls a WCF web service (basicHTTPBinding, using XML messaging, hoasted in a Windows Service) every 500ms (counted after the conclusion of each web service call).  The function returns an array of enums (NEVER more than two enums returned at a time).  The application runs just fine for a couple of minutes and then all of the sudden I get the dreaded OutOfMemoryException as I try to execute the web service call.  It almost seems like the framework is grabbing memory to handle the sending and receiving of the web service messages and then it never frees it up again.

The stack trace for the error looks like this:

   at System.Reflection.Assembly.GetManifestResourceStream(String name)
   at System.Reflection.Assembly.GetManifestResourceStream(Type type, String name)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at System.Resources.ResourceManager.GetString(String name)
   at System.SRSupport.GetString(String key, Object[] args)
   at System.SRSupport.GetString(Int32 resource, Object[] args)
   at System.Xml.Res.GetString(Int32 resource, Object[] args)
   at System.Xml.Serialization.XmlSerializationReflector.AddType(Type type, Boolean encoded, String defaultNS, Boolean genericNullableArg)
   at System.Xml.Serialization.XmlSerializationReflector.FindType(Type type, Boolean encoded, Boolean genericNullableArg, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializationReflector.FindType(Type type, Boolean encoded, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializationReflector.ResolveLiteralTypeUsingDeclaredType(Type memberType, String defaultNS, LogicalType& type, LogicalType& elementType, Boolean& isArray)
   at System.Xml.Serialization.XmlSerializationReflector.ResolveLiteralType(String attrDataType, Type attrType, Type memberType, String defaultNS, Boolean& isArray, LogicalType& type, LogicalType& elementType)
   at System.Xml.Serialization.XmlSerializationReflector.ReflectXmlElementAttributes(Type memberType, LogicalMemberValue memberValue, String memberName, LiteralAttributes attrProv, AccessorCollection memberAccessors, String defaultName, String defaultNS, Type& serializingType, Boolean& shouldBeOrdered)
   at System.Xml.Serialization.XmlSerializationReflector.ReflectLiteralMemberValue(Type memberType, String memberName, LiteralAttributes attrProv, String defaultName, String defaultNS, IEntityFinder memberFinder, Boolean canRead, Boolean canWrite, Boolean& shouldBeOrdered)
   at System.Xml.Serialization.XmlSerializationReflector.ReflectMemberValue(Type memberType, ICustomAttributeProvider attrProv, String defaultName, String defaultNS, IEntityFinder memberFinder, Fetcher fetcher, Fixup fixup, MemberValueCollection members, Boolean encoded, Boolean canRead, Boolean canWrite, Byte& specialType, Boolean& shouldBeOrdered)
   at System.Xml.Serialization.XmlSerializationReflector.addComplexTypeMemberHelper(Type type, MemberInfo member, Boolean encoded, String defaultNS, Boolean& shouldBeOrdered, IEntityFinder choiceFinder, MemberValueCollection members, String typeNS, String defaultMemberNS, Int32& sequenceId)
   at System.Xml.Serialization.XmlSerializationReflector.AddComplexType(Type type, TypeAttributes attrs, String typeName, String typeNS, Boolean typeIsNullable, Boolean encoded, String defaultNS, Boolean genericNullableArg)
   at System.Xml.Serialization.XmlSerializationReflector.AddType(Type type, Boolean encoded, String defaultNS, Boolean genericNullableArg)
   at System.Xml.Serialization.XmlSerializationReflector.FindType(Type type, Boolean encoded, String defaultNamespace, Boolean searchIntrinsics)
   at System.Xml.Serialization.XmlSerializer.findTypeByType(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, String defaultNamespace)
   at Microsoft.Tools.ServiceModel.CFClientBase`1.CFContractSerializer.createSerializer(XmlQualifiedName wrapper)
   at Microsoft.Tools.ServiceModel.CFClientBase`1.CFContractSerializer..ctor(CFContractSerializerInfo info)
   at Microsoft.Tools.ServiceModel.CFClientBase`1.GetContractSerializer(CFContractSerializerInfo info)
   at Microsoft.Tools.ServiceModel.CFClientBase`1.getResult[TRESPONSE](Message reply, CFInvokeInfo info)
   at Microsoft.Tools.ServiceModel.CFClientBase`1.Invoke[TREQUEST,TRESPONSE](CFInvokeInfo info, GetPendingActionsRequest request)
   at Motorola.SSP.CF.Communication.DaWebServiceContractClient.GetPendingActions(GetPendingActionsRequest request)
   at Motorola.SSP.CF.Communication.DaWebServiceContractClient.GetPendingActions(String sessionId)
   at Motorola.SSP.CF.Communication.DaCommClient.ClientThread()

My application literally does nothing else besides calling this one function.

Any help would be appreciated!
0
Comment
Question by:axnst2
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
8 Comments
 
LVL 25

Expert Comment

by:apeter
ID: 39782305
Please past the wcf code, so that we see whether are there any memory leaks. Like threads, DB connections, file access etc.
0
 

Author Comment

by:axnst2
ID: 39782315
I assume that you'd like to see the client side code since that's where I'm getting the exception, correct?
0
 

Author Comment

by:axnst2
ID: 39782385
Here's the client code:

Please keep in mind that the client is running on Windows Mobile (.NET CF 3.5)

public partial class Form1 : Form
    {
        DaCommClient _DAClient = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (_DAClient == null)
                {
                    _DAClient = new DaCommClient("192.168.1.150", 9091, new System.Version("1.0.0.0"));
                }

                _DAClient.ValidateLicense(new Guid("00000000-4CCC-15E1-282C-9486E71E71C6"));

            }
            catch (Exception er)
            {
                MessageBox.Show(er.ToString());
            }
        }
    }

public class DaCommClient : IDisposable
    {
        // internal fields
        private object _communicationLock = new object();
        private DaWebServiceContractClient _webService;
        private Thread _clientThread;
        private bool _shutdownThread;
        private Guid _uii;
        private string _serverAddress;
        private int _serverPort;
        private int _serverQueryInterval;
        private Guid _conectedDeviceComponentType = Guid.Empty;

        private string _sessionId = string.Empty;
        private static System.Version _applicationVersion = null;        

        public DaCommClient(string serverAddress, int serverPort, System.Version currentApplicationVersion)
        {
            _applicationVersion = currentApplicationVersion;

            // validate our params
            if (string.IsNullOrEmpty(serverAddress)) throw new ArgumentException("Server address is required and cannot be null or empty.");
            if (serverPort < 1 && serverPort > ushort.MaxValue) throw new ArgumentException("Server port is invalid. Must be between 1 and " + ushort.MaxValue);

            // initialize
            _serverAddress = serverAddress;
            _serverPort = serverPort;
            _serverQueryInterval = 500;

            // create the web service
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MaxReceivedMessageSize = 1024 * 1024;
            string address = string.Format("http://{0}:{1}/SSP/DA/Web", _serverAddress, _serverPort);
            _webService = new DaWebServiceContractClient(binding, new EndpointAddress(address));
            
        }

        public void Dispose()
        {
            Close();
        }
        
        public bool ValidateLicense(Guid uii)
        {
            lock (_communicationLock)
            {
                _uii = uii;
                if (StartNewSession())
                {
                    // start the client thread
                    _shutdownThread = false;
                    _clientThread = new Thread(new ThreadStart(ClientThread));
                    _clientThread.Start();

                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        public void Close()
        {
            // shutdown the thread
            if (_clientThread != null)
            {
                // stop the main thread
                _shutdownThread = true;
                if (!_clientThread.Join(5000))
                {
                    _clientThread.Abort();
                }
            }
        }

        private void ClientThread()
        {
            // set the connection state

            while (!_shutdownThread)
            {
                MobileClientPendingAction[] actions = null;

                try
                {
                    lock (_communicationLock)
                    {
                        actions = _webService.GetPendingActions(_sessionId);
                    }
                }
                catch (CFFaultException ex)
                {
                    FaultMessage msg = new FaultMessage(ex.FaultMessage);
                    if (msg.ErrorCode == FaultErrorCode.InvalidSession)
                    {
                        try
                        {
                            // try to start a new session
                            StartNewSession();
                        }
                        catch (CommunicationException)
                        {
                            // do nothing here
                        }
                    }
                }
                catch (Exception er)
                {
                    throw er;
                }

                // wait before making another request
                SmartSleep(_serverQueryInterval);
            }
        }
        
        private bool StartNewSession()
        {
            lock (_communicationLock)
            {
                try
                {
                    if (_applicationVersion == null)
                    {
                        throw new Exception("Current application version must be set prior to attempting to create a new session");
                    }

                    if (string.IsNullOrEmpty(_sessionId))
                    {
                        _sessionId = _webService.ValidateLicense(_uii.ToString(), "37978D90-FF9D-427A-834D-AB032BADE1ED");
                    }

                    return true;
                }
                catch (CFFaultException ex)
                {
                    FaultMessage msg = new FaultMessage(ex.FaultMessage);
                    if (msg.ErrorCode == FaultErrorCode.NoLicenseAssigned)
                    {
                        if (!string.IsNullOrEmpty(_sessionId))
                        {
                            // raise an event if we had a session
                            _sessionId = null;
                        }

                        return false;
                    }
                    else
                    {
                        throw new CommunicationException(msg.Message);
                    }
                }
                catch (Exception ex)
                {
                    throw new CommunicationException("Error communicating with the server.", ex);
                }
            }

            return false;
        }

        private void SmartSleep(int ms)
        {
            int timeToSleep = ms;
            while (timeToSleep > 0)
            {
                // break early if the thread is being shutdown
                if (_shutdownThread)
                {
                    break;
                }

                Thread.Sleep(100);
                timeToSleep -= 100;
            }
        }

        public static Version Convert(System.Version version)
        {
            Version convertedVersion = new Version();

            convertedVersion._Major = version.Major;
            convertedVersion._Minor = version.Minor;
            convertedVersion._Build = version.Build;
            convertedVersion._Revision = version.Revision;

            return convertedVersion;
        }
    }

Open in new window

0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 25

Expert Comment

by:apeter
ID: 39782941
From the first glance, you are not calling the dispose method of "DaCommClient". Can you please do like below and see it improves ?


private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (_DAClient == null)
                {
                    _DAClient = new DaCommClient("192.168.1.150", 9091, new System.Version("1.0.0.0"));
                }

                _DAClient.ValidateLicense(new Guid("00000000-4CCC-15E1-282C-9486E71E71C6"));

            }
            catch (Exception er)
            {
                MessageBox.Show(er.ToString());
            }
            finally
{
 if (_DAClient != null)
                {
                        _DAClient.Dispose();
                  }
        }
0
 

Author Comment

by:axnst2
ID: 39783272
That's not it.  I call Dispose in from_Closing.  Please take a look at the function ValidateLicense.  It starts a baground thread that keeps calling _webService.GetPendingActions over-and-over again (in order to test the issue), and therefore, I don't want to dispose of the client.

I fixed the problem but I don't understand why my fix is a fix.  So instead of using NetCFSvcUtil.exe to generate the web service proxy objects, I simply used the "Add Web Reference" function built into VS2008 (on the client side) and my problem went away.  Can you explain to me why?
0
 
LVL 25

Accepted Solution

by:
apeter earned 500 total points
ID: 39784789
I don't see the "from_Closing" method. but it is always better to dispose every time a request is made by clicking the button rather than at form closing.


Please check this link to see why the memory problem occurs due the exe, http://social.msdn.microsoft.com/Forums/vstudio/en-US/97b84107-065e-4006-8565-536749349d67/memory-leak-in-windows-mobile-wcf-proxy-client?forum=wcf
0
 

Author Closing Comment

by:axnst2
ID: 39785430
Thank you, the explanation you posted regarding the bug in the NetCFSvcUtil utility explains why adding a "web reference" instead of using the NetCFSvcUtil utility fixed my OutOfMemoryException problem.  It's sad that Microsoft obviously knows about this bug and has done nothing to fix it.  This bug basically renders the utility useless.
0
 

Author Comment

by:axnst2
ID: 39785794
Just as a side note, as an unexpected (but very welcome) side effect, changing from NetCFSvcUtil to the "Add Web Reference" method has DRASTICALLY improved the overall speed of my ENTIRE application, even parts that never even call the web service!!!  :)
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Consuming WCF in Action Script 3 [ flash Develop ] 3 337
,net web service 1 106
VB.net and soap 14 139
Web service and database connection 9 30
While working on Silverlight and WCF application, I faced one issue where fault exception occurred at WCF operation contract is not getting propagated to Silverlight client. So after searching net I came to know that it was behavior by default for s…
Here I am going to explain creating proxies at runtime for WCF Service. So basically we use to generate proxies using Add Service Reference and then giving the Url of the WCF service then generate proxy files at client side. Ok, what if something ge…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question