Visual C# Developer Center > Visual C# Forums > Visual C# General > System.Timers and Web service problem
Ask a questionAsk a question
 

QuestionSystem.Timers and Web service problem

  • Tuesday, November 03, 2009 4:58 PMMathieu Maes Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi,

    I've been trying to get this to work for quite some time now. This is
    my goal: When my application starts, it has to call a web service
    immediately, and setup a timer to call the same method every few
    minutes. This is my code:

     

    Class MyApplication
    {
    ...
            private System.Timers.Timer syncTimer;
    
            Public void Startup()
            {
                            Logger.Debug("Syncing at startup + setting up timer");
                            Core.Sync();
                            syncTimer = new System.Timers.Timer();
                            syncTimer.Elapsed += new System.Timers.ElapsedEventHandler(syncTimer_Elapsed);
                            syncTimer.Interval = 60000; //Perform sync every minute
                            syncTimer.AutoReset = true;
                            syncTimer.Start();
             }
    
            void syncTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                    Core.Sync();
            }
    }
    
    Public static class Core
    {
            public static void Sync()
            {
                    // Following line instanciates web service and adds the correct URL from settings
                    ionSyncPlugin.ionSyncWS.Webservice ionPmWS = Library.InitWebservice();
                    ionPmWS.GetUserProjectsCompleted += new ionSyncPlugin.ionSyncWS.GetUserProjectsCompletedEventHandler(getProjectsCompleted);
                    ionPmWS.GetUserProjectsAsync(settings.Login,Library.GetMD5(settings.Password));
            }
    
            private static void  getProjectsCompleted(object sender, ionSyncPlugin.ionSyncWS.GetUserProjectsCompletedEventArgs e)
            {
                   // Do some stuff with the result
            }
    }
    
    


    When the program starts, the first Sync (being started from Startup())
    works fine. But whenever the timer fires the 'elapsed' event, the
    program performs a request, but the getProjectsCompleted eventhandler
    is never started.

    According to my findings, the request reaches the web service, and the
    method (getProjects) is being processed on server side successfully.
    I've also tried testing the application with the web service running
    locally in Visual Studio. The result was the same.

    I've tried setting up the timer object inside the Core class instead
    of the application class, but the result was just the same.

    Can anyone explain to me why this is happening ?

    Thanks in advance!

    Kind regards,
    Mathew

All Replies

  • Wednesday, November 04, 2009 8:47 AMGeert van Horrik Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    If you call Sync twice in your constructor, does it work the second time as well (so test if you are able to call the web service twice without any threading).


    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
  • Wednesday, November 04, 2009 1:35 PMStephen Cleary Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    It's possible that this is a GC issue.

    In Sync, you're creating an object that becomes eligible for GC at the end of Sync.

    Add a GC.Collect() to the end of Sync, and see if it stops working completely. If it does, then change Sync so that it either uses a shared proxy (created in Startup) or saves the proxy somewhere until its async method completes.

           -Steve
    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ

    Microsoft Certified Professional Developer
  • Monday, November 09, 2009 9:31 PMMathieu Maes Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Thanks for your replies, Steve and Geert. I may have found the cause.

    Above code isn't complete (I didn't think it was relevant at the time). I also have a Windows form containing an image and a status bar:
    Class MyApplication
    {
            public LoaderForm Loader;
    ...
    }
    
    The form is being instanciated in the Startup() method. I have a public method that I call here and there inside the Core class to provide feedback to the user about what's happening:
            public void setLoadingText(string message)
            {
                    lblLoading.Text = message;
                    this.Refresh();
            }
    

    The process works perfect when Core.Sync is called at Startup(). I can also call Core.Sync as much as I want using a button in the program. But it doesn't work at all when Core.Sync is called from the timer event. The Loader window stays on the screen and shows "not responding". Every time the timer triggers, a new window show up "not responding", even though it's the same instance.

    When I comment out all calls to Loader.setLoadingText, it works like a charm!

    I read about using control.Invoke when you update a control from another thread then the one it's been created, and using a "delegate". I think this might help me out, but the problem is I don't really understand how to do it. Where should I put the delegate method ? Can anyone explain how I implement a delegate method in my code ?

    Thanks in advance!