System.Timers and Web service problem
- 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
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!- 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 - 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:
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:Class MyApplication { public LoaderForm Loader; ... }
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!


