Results 1 to 18 of 18

Thread: Winforms timer woes...

  1. #1

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Winforms timer woes...

    Hey folks,

    I'm using VB 2005 Express, obviously with .NET framework 2.0, and I've run into something a little odd..

    I have myself a program which runs in the background, and uses a FileSystemWatcher. It logs changes to a certain directory, indicating that users have changed settings, etc..., etc..

    Anyhow, one of the apps which changes settings does it in such a way that it deletes a file, then immediately creates a new file. So, to separate this type of event from a straight up deletion event, I put this code in the event handler (deletedlist is just an arraylist):

    VB Code:
    1. Private Sub FW_Deleted(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs)
    2.         deletedlist.Add(e.FullPath.ToUpper)
    3.         deletetime.Interval = 2000
    4.         deletetime.Enabled = True
    5.     End Sub
    6.  
    7.     Private Sub deletetime_Tick(ByVal sender As Object, ByVal e As System.EventArgs)
    8.         deletetime.Stop() 'This is a "run once" timer.
    9.         For i As Integer = 0 To deletedlist.Count - 1
    10.             Dim SW As New IO.StreamWriter(path + "global.log", True)
    11.             Dim datestr As String = Date.Now.ToShortTimeString + " on " + Date.Now.ToShortDateString
    12.             SW.WriteLine(deletedlist(i).ToString + " was deleted at " + datestr)
    13.             SW.Close()
    14.             Threading.Thread.Sleep(500) 'Avoid windows file conflicts.
    15.         Next
    16.         deletedlist.Clear() 'Remove all items from list, as they've been handled.
    17.     End Sub

    You will notice neither sub has a handles clause at the end. Fair enough. Here they are in the forms load event:

    VB Code:
    1. AddHandler FW.Deleted, AddressOf FW_Deleted
    2.  AddHandler deletetime.Tick, AddressOf Me.deletetime_Tick

    So, you would think this would work eh? The tick event never fires. Now, Sometimes I think I know what I'm doing, so I tried just dragging and dropping instead of using AddHandler, just incase I've got that all wrong. Still no dice.

    I then started a new project, drag and dropped a winforms timer, and a filesystemwatcher object onto the form, and basically did the same thing without any other code, and it never fires the tick sub. I remove the code from the filesystemwatcher's event handler, stick it in a generic button click sub, and it works fine. Logically, next, I put a breakpoint on the filesystemwatcher's event code - as soon as I delete a file, boom, it fires. Line by line I step through the enabling and setting of the interval.. yet the tick event (which I've also got a breakpoint at) never fires.


    Finally, I replace my Winforms timer with a System.Timers.Timer, change the words tick to elapsed, and everything's fine.

    Any clue why the winforms timer.Tick event will not fire if Enabled is turned on by a deleted event of a FileSystemWatcher?

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  2. #2
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    This is a guess as Ive not used 2005 yet. When updating a control on a form from a different thread sometimes it failed to work in 2003 (treeview mainly). You had to reference the main form thread. Theres a me.something or other for it.

    I spose you could just create a new instance of the timer there and then and attempt to fire it off. As I say Ive not used wintimer, so its just a stab till someone whos used it comes along .

  3. #3

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Winforms timer woes...

    It's all on the same form though... I have a password change form, and a login form, but neither of those are related to the delete and timer events..

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  4. #4
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    Maybe I wasnt clear enough. It doesnt matter that its on the same form, you must use the same thread that created the object, to "change/use" it (for the treeview control at least). If you tried to add a new node from an outside event for example, it would error.

    Ive just looked it up and its called Invoke. The event raised by the FW is not the forms thread, so call this:

    VB Code:
    1. Private Delegate Sub delTimerStarter()
    2.     Private Sub StartTimer()
    3.         Timer1.Enabled = True
    4.     End Sub
    5.  
    6.    'Then call this from inside your event
    7.    Me.Invoke(New delTimerStarter(AddressOf StartTimer))

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    It works for me.
    Attached Images Attached Images  
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    Note that Timer.Tick events are raised in the UI thread, so using delegates is not required. That's assuming that the Timer was created in the UI thread of course.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    conipto is adding the handle manually from the load event (which I assume is called by an outside thread!)

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    Quote Originally Posted by Grimfort
    conipto is adding the handle manually from the load event (which I assume is called by an outside thread!)
    But he said that he tried it in the designer too and it still didn't work. Apart from that, he's using AddHandler in the form's Load event handler, which must be executed in the UI thread. Either way, there's nothing here that I can see that is happening in a different thread. If there was then you'd have an exception being thrown when debugging as by default VS 2005 won't let you make cross-thread calls to control members.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Winforms timer woes...

    Ok, so I tried exactly what you had, and it worked. Perhaps in my test I only drag and dropped the timer

    However, if I take your code, and create my filewatcher and it's handler in code, the deleted event still fires, but I never see my timer tick.. (Adding Me in the Addhandler declaration has no effect either)

    Bill
    Attached Images Attached Images  
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  10. #10
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    Ooooo thats a nice feature. I know we had to Invoke a few times to change controls on events (IP) from outside. I thought the load would be the forms thread but ran out of ideas .

    heres what conipto said:
    Finally, I replace my Winforms timer with a System.Timers.Timer, change the words tick to elapsed, and everything's fine.

    Go on, try the delegate thing out, prove me wrong .

  11. #11

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Winforms timer woes...

    Quote Originally Posted by Grimfort
    Ooooo thats a nice feature. I know we had to Invoke a few times to change controls on events (IP) from outside. I thought the load would be the forms thread but ran out of ideas .

    heres what conipto said:
    Finally, I replace my Winforms timer with a System.Timers.Timer, change the words tick to elapsed, and everything's fine.
    Yes, but my brain still wants to know why.. after research MSDN says the System timer is more accurate anyways (so I'll probably keep using it in the future!) but I'd still like to know why it doesn't work that way..

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  12. #12
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    Use the delegate I know you want to .


    I can only guess that your handler for the deleted event is not linked to your UI thread. Just having a little search for more info.

  13. #13
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    OK, I've made a breakthrough. Grimfort was indeed on the right track. When you create an FSW at run time the default is for its events to be raised on a thread other than the UI thread. What you need to do is add this line to have its events raised on the UI thread:
    VB Code:
    1. myFileSystemWatcher.SynchronizingObject = Me
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  14. #14

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Winforms timer woes...

    Quote Originally Posted by jmcilhinney
    OK, I've made a breakthrough. Grimfort was indeed on the right track. When you create an FSW at run time the default is for its events to be raised on a thread other than the UI thread. What you need to do is add this line to have its events raised on the UI thread:
    VB Code:
    1. myFileSystemWatcher.SynchronizingObject = Me
    Excellent. I wonder how many other objects this is the case for?

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  15. #15
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    SynchronizingObject is a property of the following classes:

    Process
    FileSystemwatcher
    MessageQueue
    System.Timers.Timer
    EventLog
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  16. #16

    Thread Starter
    Frenzied Member conipto's Avatar
    Join Date
    Jun 2005
    Location
    Chicago
    Posts
    1,175

    Re: Winforms timer woes...

    Quote Originally Posted by jmcilhinney
    SynchronizingObject is a property of the following classes:

    Process
    FileSystemwatcher
    MessageQueue
    System.Timers.Timer
    EventLog
    Interesting that the same thing didn't cause a problem with a System.Timers.Timer...

    Bill
    Hate Adobe Acrobat? My Codebank Sumbissions - Easy CodeDom Expression evaluator: (VB / C# ) -- C# Scrolling Text Display

    I Like to code when drunk. Don't say you weren't warned.

  17. #17
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: Winforms timer woes...

    The WinForms Timer is optimised for WinForms apps, which means it is probably tuned to work on the UI thread. I would have thought that if the call to its Start method wasn't going to work you would have had an exception thrown, but I guess that must just be the case for controls. The System.Timers.Timer class has no such affinity for the UI thread so its members must not care from where they are called. I don't think it has anything to do with the SynchronizingObject property of the Timer, although perhaps if you do set it for the FSW then it won't work with a Timers.Timer.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  18. #18
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780

    Re: Winforms timer woes...

    Score! At least I know for when I use 2005. Good investigation work.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width