how to pass a variable to a timer's handler? - Page 2


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 38

Thread: how to pass a variable to a timer's handler?

  1. #16
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?


    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    > > But if response times are in the millisecond range, that would not stop

    > repeated requests.
    >
    > ? Of course it would. { Is there a request for PC#2 already in the table?
    > Yes - ignore this one }


    If the user clicks at a rate of .5 seconds (500 ms) and the send and response
    happens at a rate of .05 seconds (50 ms) then the user is able to repeatedly
    click for repeated transactions.

    >
    > > What if, for example, it was desired to restrict requests to one every
    > > 10 seconds to keep the DB from being updated so often?

    >
    > That is exactly what he was asking for.


    Then your solution would not have worked because 50 ms after the request
    was sent, it would have been responded to, and removed:

    >> When a response comes in, you simply delete the associated entry from the
    >> hash table. You can detect multiple clicks by simply looking at the HashTable
    >> and seeing if that key already exists, in which case you ignore the new click.


    >
    > What you describe is similar to what I suggested, except you are suggesting
    > a queue instead of a hashtable.


    More or less.... We both envisioned a solution without using the Timer.

    > Since the situation only calls for (and is trying to enforce) one
    > outstanding request at any one time, why use a queue,


    Because they would be in chronological order, making removal of old
    requests a trival matter. (Enter a loop dequeuing the top object until an
    object's time component is less than 10 seconds old)


    > but more importantly,
    > a queue cannot be scanned to see if a request is outstanding (you only have
    > access to the end value)


    Check out the .Contains property of a queue.

    > The requirement is for a data structure that allows a keyed pair (keyed on
    > PC name) so a HashTable is the fastest and most applicable solution.


    The queue holds objects, whatever was needed in the way of ID and data
    could be made a member of that object. That object might also be delegated
    to handle the response, calling a function to update the DB when a response is
    received.

    Both methods could be made workable, I was just offering an alternate route,
    as I mentioned in my other message: I was going to suggest ....

    LFS



  2. #17
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?


    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbb3878@tnews.web.devx.com...
    >
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    > > > But if response times are in the millisecond range, that would not

    stop
    > > repeated requests.
    > >
    > > ? Of course it would. { Is there a request for PC#2 already in the

    table?
    > > Yes - ignore this one }

    >
    > If the user clicks at a rate of .5 seconds (500 ms) and the send and

    response
    > happens at a rate of .05 seconds (50 ms) then the user is able to

    repeatedly
    > click for repeated transactions.


    I presumed that he didn't want to have multiple outstanding requests (like a
    sort of key debounce), rather than prevent multiple requests within a short
    timespan, but even if this is is the case then I still see no use for a
    queue. In my solution you would simply not remove the entry when a response
    came in, and let the 'cleanup' timer remove the entry when the 'debounce'
    time was exceeded.
    What 'multiple requests' do you envisage being stored in the queue for each
    remote machine?

    > > > What if, for example, it was desired to restrict requests to one

    every
    > > > 10 seconds to keep the DB from being updated so often?

    > >
    > > That is exactly what he was asking for.

    >
    > Then your solution would not have worked because 50 ms after the request
    > was sent, it would have been responded to, and removed:
    >
    > >> When a response comes in, you simply delete the associated entry from

    the
    > >> hash table. You can detect multiple clicks by simply looking at the

    HashTable
    > >> and seeing if that key already exists, in which case you ignore the new

    click.
    >
    > >
    > > What you describe is similar to what I suggested, except you are

    suggesting
    > > a queue instead of a hashtable.

    >
    > More or less.... We both envisioned a solution without using the Timer.
    >
    > > Since the situation only calls for (and is trying to enforce) one
    > > outstanding request at any one time, why use a queue,

    >
    > Because they would be in chronological order, making removal of old
    > requests a trival matter. (Enter a loop dequeuing the top object until an
    > object's time component is less than 10 seconds old)
    >
    >
    > > but more importantly,
    > > a queue cannot be scanned to see if a request is outstanding (you only

    have
    > > access to the end value)

    >
    > Check out the .Contains property of a queue.


    Er... yes. You could use a collection, hashtable, arraylist or dictionary
    for these requirements, but some are better suited than others.
    I don't think you can use .Contains to perform what you suggest. It compares
    the supplied _object_ to the one in the queue. Since the queue objects
    contain more than just a key, you could not find the one you wanted. The
    only usable alternative I can see would be to use .ToArray then iterate
    through the array Even then, how do you remove the entry when you need to
    if it's not at the top of the queue?
    A hash is designed to do exactly this:
    If myHashtable.ContainsKey(MachineName)
    I suppose an alternative would be to read from one and write the values into
    another, checking each one for the value you want.

    > > The requirement is for a data structure that allows a keyed pair (keyed

    on
    > > PC name) so a HashTable is the fastest and most applicable solution.

    >
    > The queue holds objects, whatever was needed in the way of ID and data
    > could be made a member of that object. That object might also be

    delegated
    > to handle the response, calling a function to update the DB when a

    response is
    > received.
    >
    > Both methods could be made workable, I was just offering an alternate

    route,
    > as I mentioned in my other message: I was going to suggest ....


    It is indeed an alternate route. I'm not saying mine is any better or worse,
    I am simply questioning why your suggestion is based around a queue

    Cheers,
    Jason



  3. #18
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote

    > I presumed that he didn't want to have multiple outstanding requests (like a
    > sort of key debounce), rather than prevent multiple requests within a short
    > timespan, but even if this is is the case then I still see no use for a
    > queue.


    It could work, just as your solution could work....

    > In my solution you would simply not remove the entry when a response
    > came in, and let the 'cleanup' timer remove the entry when the 'debounce'
    > time was exceeded.


    What timer? I thought the purpose was to remove the OP's timer dependancy.


    > > > Since the situation only calls for (and is trying to enforce) one
    > > > outstanding request at any one time, why use a queue,

    > >
    > > Because they would be in chronological order, making removal of old
    > > requests a trival matter. (Enter a loop dequeuing the top object until an
    > > object's time component is less than 10 seconds old)



    > >
    > > Check out the .Contains property of a queue.

    >
    > I don't think you can use .Contains to perform what you suggest. It compares
    > the supplied _object_ to the one in the queue. Since the queue objects
    > contain more than just a key, you could not find the one you wanted.


    You got to learn to think outside the box... <g>
    The Contains method uses the Equals method to determine if some passed in
    object matches any in the queue.

    Consider an object defined as:

    Public Class QueData
    Public Name As String
    Public Ping As Date

    Public Sub New(ByVal Name As String, ByVal Ping As Date)
    Me.Name = Name
    Me.Ping = Ping
    End Sub

    Public Sub New(ByVal Name As String)
    Me.Name = Name
    Me.Ping = Now
    End Sub

    Public Overloads Overrides Function Equals(ByVal Obj As Object) As Boolean
    If Not Obj Is Nothing AndAlso Obj.GetType Is Me.GetType Then
    Return CBool(CType(Obj, QueData).Name = Me.Name)
    Else
    Return False
    End If
    End Function
    End Class



    Now, any time Equals is called on that object, the included function is
    used that compares any of the data that needs to be checked (I only
    checked the name for a demo). In other words

    Dim o1 As QueData = New QueData("N1", New Date(2002, 1, 1))
    Dim o2 As QueData = New QueData("N2", New Date(2001, 2, 2))
    Dim q As New Queue()

    q.Enqueue(o1)
    q.Enqueue(o2)

    MsgBox(q.Contains(New QueData("N3"))) ' False

    MsgBox(q.Contains(New QueData("N1"))) ' True



    > It is indeed an alternate route. I'm not saying mine is any better or worse,
    > I am simply questioning why your suggestion is based around a queue


    That's what struck my mind when I read the question, so that is what I
    built my suggestion on. The fact that there is a time element, means some had
    to be held on to until a certain time elapsed. A queue keeps those objects
    in chronological order, as would any other type of collection. Because the
    size varies, I go to collections, when the size will be (more or less) fixed,
    I think of arrays....

    LFS



  4. #19
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbb8c08@tnews.web.devx.com...
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    >
    > > I presumed that he didn't want to have multiple outstanding requests

    (like a
    > > sort of key debounce), rather than prevent multiple requests within a

    short
    > > timespan, but even if this is is the case then I still see no use for a
    > > queue.

    >
    > It could work, just as your solution could work....
    >
    > > In my solution you would simply not remove the entry when a response
    > > came in, and let the 'cleanup' timer remove the entry when the

    'debounce'
    > > time was exceeded.

    >
    > What timer? I thought the purpose was to remove the OP's timer

    dependancy.

    No, the purpose was to solve his problem. The only mention of removing
    timers was in a solution I posted.
    Using a HashTable doesn't require the timer anyway, I simply mention it as a
    way of removing entries for machines that are no longer required.

    > > > > Since the situation only calls for (and is trying to enforce) one
    > > > > outstanding request at any one time, why use a queue,
    > > >
    > > > Because they would be in chronological order, making removal of old
    > > > requests a trival matter. (Enter a loop dequeuing the top object

    until an
    > > > object's time component is less than 10 seconds old)

    >
    >
    > > >
    > > > Check out the .Contains property of a queue.

    > >
    > > I don't think you can use .Contains to perform what you suggest. It

    compares
    > > the supplied _object_ to the one in the queue. Since the queue objects
    > > contain more than just a key, you could not find the one you wanted.

    >
    > You got to learn to think outside the box... <g>
    > The Contains method uses the Equals method to determine if some passed in
    > object matches any in the queue.
    >
    > Consider an object defined as:
    >
    > Public Class QueData
    > Public Name As String
    > Public Ping As Date
    >
    > Public Sub New(ByVal Name As String, ByVal Ping As Date)
    > Me.Name = Name
    > Me.Ping = Ping
    > End Sub
    >
    > Public Sub New(ByVal Name As String)
    > Me.Name = Name
    > Me.Ping = Now
    > End Sub
    >
    > Public Overloads Overrides Function Equals(ByVal Obj As Object) As

    Boolean
    > If Not Obj Is Nothing AndAlso Obj.GetType Is Me.GetType Then
    > Return CBool(CType(Obj, QueData).Name = Me.Name)
    > Else
    > Return False
    > End If
    > End Function
    > End Class
    >
    >
    > Now, any time Equals is called on that object, the included function is
    > used that compares any of the data that needs to be checked (I only
    > checked the name for a demo). In other words
    >
    > Dim o1 As QueData = New QueData("N1", New Date(2002, 1, 1))
    > Dim o2 As QueData = New QueData("N2", New Date(2001, 2, 2))
    > Dim q As New Queue()
    >
    > q.Enqueue(o1)
    > q.Enqueue(o2)
    >
    > MsgBox(q.Contains(New QueData("N3"))) ' False
    >
    > MsgBox(q.Contains(New QueData("N1"))) ' True


    I know how to implement an Equals function, but given the choice between
    these 50 lines of additional (and less efficient) code, and
    MsgBox(myHashtable.ContainsKey(MachineName))
    ???
    "If all you have is a hammer, everything looks like a nail" - Yes, you can
    batter almost any data structure to do what you like.
    Perhaps an important part of OO design is learning how to recognise what
    fits _inside_ the box?

    A couple of questions still not addressed:
    1. Can you remove entries from the queue if you decide you need to?
    2. What 'multiple requests' do you envisage being stored in the queue for
    each remote machine? Surely you don't mean that I should use one queue for
    all machines?? Use a queue as a collection?
    3. Why would you use a queue? This has still not been explained.

    The only possible advantage I can see of a queue in a situation like this is
    that you could return the values in order if you wanted to display them, and
    it guarantees the oldest item would be on the end of the queue, but does
    this help us at all or matter?
    The function to check the machine was allowed to be queried (with the Now()
    bit simplified) would be:

    Queue:
    While myQueue.Peek().TimeOutTime<Now() Then
    myQueue.Dequeue 'Strip all timed-out entries
    Wend
    Return myQueue.Contains(New QueData(MachineName))
    (Note that we _must_ dequeue the old items, or our queue will grow and grow)

    For a hash table:
    Return (myHashTable.ContainsKey(MachineName) AndAlso
    myHashTable.Item(MachineName).TimeOutTime<Now() )
    (Note that we will never have more entries in our hash table than we have
    machines, but they could be removed if it was felt necessary by adding
    myHashTable.Remove(MachineName))

    > > It is indeed an alternate route. I'm not saying mine is any better or

    worse,
    > > I am simply questioning why your suggestion is based around a queue

    >
    > That's what struck my mind when I read the question, so that is what I
    > built my suggestion on. The fact that there is a time element, means some

    had
    > to be held on to until a certain time elapsed. A queue keeps those

    objects
    > in chronological order, as would any other type of collection. Because

    the
    > size varies, I go to collections, when the size will be (more or less)

    fixed,
    > I think of arrays....


    But a queue is an abstract data type and an array is not. Surely you should
    be considering which ADT to use?

    Cheers,
    Jason



  5. #20
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    > > > > Check out the .Contains property of a queue.
    > > >
    > > > I don't think you can use .Contains to perform what you suggest.

    >
    > I know how to implement an Equals function,


    Then why did you say you thought it could not be done?



    > but given the choice between
    > these 50 lines of additional (and less efficient) code, and
    > MsgBox(myHashtable.ContainsKey(MachineName))
    > ???


    That will not work as you state. You have not created the hash table,
    and you have taken on the assumption that there will only be one item of data
    associated with each key. If the OP's design expands to require 3 more items
    of data, he has to follow that table everwhere in code to include more data, or,
    he has to make the hash table use an object, instead of just a name/value pair.
    By the time you create an object for the hash table and actually use it, you will
    have signifcantly more than the one line you show.

    I could just as easily have said the same thing:

    > MsgBox(q.Contains(New QueData("N1"))) ' True


    There, 1 line to check for a match, that is as much as you've done.

    I am not going to get argumentative, as you seem to be heading toward.
    You think you can get by with a name/value pair, while I think a more
    robust object would be better suited for the task. I don't know why you
    think a queue is any less efficient than a hashtable, but I have no doubt the
    user can not click fast enough to notice a difference. (The difference
    between O(1) and O(3) or O(5) is not significant)


    > "If all you have is a hammer, everything looks like a nail" - Yes, you can
    > batter almost any data structure to do what you like.


    > Perhaps an important part of OO design is learning how to recognise what
    > fits _inside_ the box?


    I guess I don't see how adding procedural code to manage the transmision and
    DB updating in addition to the name/value table, is more OO than using a collection
    of objects that send out a request when queued and updates the DB when
    responded to. Sure an object is more expensive than one piece of data, but
    that name/value approach is not very forward looking. All it handles is a name/value
    pair so as soon as a change is needed to add one more piece of data to the group
    (like IP address) that hash table alone, becomes inadequate.


    > A couple of questions still not addressed:
    > 1. Can you remove entries from the queue if you decide you need to?


    Yes.

    > 2. What 'multiple requests' do you envisage being stored in the queue for
    > each remote machine? Surely you don't mean that I should use one queue for
    > all machines??


    You have misunderstood, those questions do not apply. I said the user clicks
    at a slower rate than the response time, that means he can click repeatedly,
    each sending out a request, which was precisely what the OP wanted to avoid.
    That was why your suggestion would not work as you first indicated.


    > 3. Why would you use a queue? This has still not been explained.


    Why are you not reading my responses? I have answered this twice already.
    It doesn't have to be a queue, a simple collection will work, but the
    standard Collection does not have a .Contains property. It should not be
    a fixed array because the number of user clicks (on different clients) is
    undetermined.

    >
    > The only possible advantage I can see of a queue in a situation like this


    The main advantage is that an object is expandable, a name/value pair is not.


    > But a queue is an abstract data type and an array is not. Surely you should
    > be considering which ADT to use?


    Take another look, your hashtable is a type of collection that implements 6
    different interfaces, the queue implements only half of those. Your hash table
    (alone) is locked to the name/value structure, a collection of objects is not.
    In addition to the table, you will have to add code to update that table when
    the request is sent, and when a response is recieved. An object can initiate
    the request and process the response and, if needed, it can raise events if
    the remote client times out, or other such conditions. In other words, an
    object can be made to encapsulate all of the behaviour needed when the
    user clicks on a client's info.

    That is all I am going to say on this topic, you are welcome to your opinions,
    I have mine, and the original poster has long since left the discussion.... <g>

    LFS








  6. #21
    brandon Guest

    Re: how to pass a variable to a timer's handler?

    i went thru other examples on using delegates..

    eg,
    Public Delegate Sub AddNodeDelegate(ByVal ShowText As String, ByVal Intg As
    Integer, ByVal Strng As String, ByVal sts As Integer)

    TreeView1.BeginInvoke(New AddNodeDelegate(AddressOf AddPC), New Object()
    {PcName, CInt(ID), RealID.ToString, 0})

    i am do not understand it 100%, but as i have seen, just like the example
    above, i need to invoke the delegate, then specifying the function/sub to be
    called..

    but in the example u gave, i do not see you doing that..

    AddHandler Timer2.Tick, AddressOf New TimerHandler("/" &
    mynode.MyStrng).OnTimer1

    the delegate OnTimerHandler was not specified anywhere..

    please correct me if i am wrong.. but is there anything wrong with the
    code?




    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote in message
    news:3dbb2694$1@tnews.web.devx.com...
    > Look up 'delegates' in the help pages. It is basically a way of

    specifying
    > a template for callback functions.
    > I'm not sure if there is some sort of inconsistency of bug in VS.Net,
    > because you shouldn't be able to delete that line, and I had the same
    > problem as you with the "does not have the same signature as delegate"

    error
    > when I was writing it. I suspect that the Delegate definition line is not
    > always being freshly compiled.
    >
    > Cheers,
    > Jason





  7. #22
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbbe11c@tnews.web.devx.com...
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    > > > > > Check out the .Contains property of a queue.
    > > > >
    > > > > I don't think you can use .Contains to perform what you suggest.

    > >
    > > I know how to implement an Equals function,

    >
    > Then why did you say you thought it could not be done?


    Please, give me a break. You could make the queue do anything if you add
    enough code. I was pointing out that a queue is not supposed to reveal any
    of its contents through anything except a dequeue function. The fact that
    there is a bodge added to the class that allows access when you add 50 lines
    of code does not make it a suitable object.

    > > but given the choice between
    > > these 50 lines of additional (and less efficient) code, and
    > > MsgBox(myHashtable.ContainsKey(MachineName))
    > > ???

    >
    > That will not work as you state. You have not created the hash table,
    > and you have taken on the assumption that there will only be one item of

    data
    > associated with each key. If the OP's design expands to require 3 more

    items
    > of data, he has to follow that table everwhere in code to include more

    data, or,
    > he has to make the hash table use an object, instead of just a name/value

    pair.
    > By the time you create an object for the hash table and actually use it,

    you will
    > have signifcantly more than the one line you show.
    >
    > I could just as easily have said the same thing:
    >
    > > MsgBox(q.Contains(New QueData("N1"))) ' True

    >
    > There, 1 line to check for a match, that is as much as you've done.


    Ah, it's clear that you have missed the point completely.
    If you run your example code above, and click 10,000 times on the same node,
    you will end up with 10,000 items in your queue, yes? The hash table ends up
    with 1.
    On the flip side, clicking on 10,000 different nodes (!?) would place 10,000
    items in both a queue and a hashtable, which was why I pointed out that you
    could remove them in a single O(1) call.
    Please look at the situation more carefully and see why I have shown that
    section of code.

    > I am not going to get argumentative, as you seem to be heading toward.
    > You think you can get by with a name/value pair, while I think a more
    > robust object would be better suited for the task. I don't know why you
    > think a queue is any less efficient than a hashtable, but I have no doubt

    the
    > user can not click fast enough to notice a difference. (The difference
    > between O(1) and O(3) or O(5) is not significant)
    >
    >
    > > "If all you have is a hammer, everything looks like a nail" - Yes, you

    can
    > > batter almost any data structure to do what you like.

    >
    > > Perhaps an important part of OO design is learning how to recognise what
    > > fits _inside_ the box?

    >
    > I guess I don't see how adding procedural code to manage the transmision

    and
    > DB updating in addition to the name/value table, is more OO than using a

    collection
    > of objects that send out a request when queued and updates the DB when
    > responded to. Sure an object is more expensive than one piece of data,

    but
    > that name/value approach is not very forward looking. All it handles is a

    name/value
    > pair so as soon as a change is needed to add one more piece of data to the

    group
    > (like IP address) that hash table alone, becomes inadequate.
    >
    >
    > > A couple of questions still not addressed:
    > > 1. Can you remove entries from the queue if you decide you need to?

    >
    > Yes.


    Great answer. Can you describe a method that involves less than 50 lines of
    code to remove an entry from the middle of the queue?
    I could write about 50 lines to modify a HashTable or SortedArray to act as
    a queue, but why would I do that? I would use a queue.

    > > 2. What 'multiple requests' do you envisage being stored in the queue

    for
    > > each remote machine? Surely you don't mean that I should use one queue

    for
    > > all machines??

    >
    > You have misunderstood, those questions do not apply. I said the user

    clicks
    > at a slower rate than the response time, that means he can click

    repeatedly,
    > each sending out a request, which was precisely what the OP wanted to

    avoid.
    > That was why your suggestion would not work as you first indicated.
    >
    >
    > > 3. Why would you use a queue? This has still not been explained.

    >
    > Why are you not reading my responses? I have answered this twice already.
    > It doesn't have to be a queue, a simple collection will work, but the
    > standard Collection does not have a .Contains property. It should not be
    > a fixed array because the number of user clicks (on different clients) is
    > undetermined.


    Jeez, this is stupid. Now you tell me that a collection would do if it only
    had a .Contains?
    What do you think the ADT behind a Collection is? It's a hash table, and of
    course it has a key!

    > >
    > > The only possible advantage I can see of a queue in a situation like

    this
    >
    > The main advantage is that an object is expandable, a name/value pair is

    not.

    Uuuurgh....

    > > But a queue is an abstract data type and an array is not. Surely you

    should
    > > be considering which ADT to use?

    >
    > Take another look, your hashtable is a type of collection that implements

    6
    > different interfaces, the queue implements only half of those. Your hash

    table
    > (alone) is locked to the name/value structure, a collection of objects is

    not.
    > In addition to the table, you will have to add code to update that table

    when
    > the request is sent, and when a response is recieved. An object can

    initiate
    > the request and process the response and, if needed, it can raise events

    if
    > the remote client times out, or other such conditions. In other words, an
    > object can be made to encapsulate all of the behaviour needed when the
    > user clicks on a client's info.


    Oh dear...
    A hash table contains a key and an _object_, not a string!
    A queue contains _only_ an object.

    > That is all I am going to say on this topic, you are welcome to your

    opinions,
    > I have mine, and the original poster has long since left the

    discussion.... <g>

    That is probably a good idea. I would suggest you study up on the different
    ADTs and their features, because you seem to be confusing a HashTable with
    an Array.
    Check this out for more info:
    http://www.aspfree.com/chapters/sams...234x_ch03.aspx

    Your concerns about the resizing of the data structure are correct, but you
    miss the point that both queues and hashtables are resizable.

    Cheers,
    Jason



  8. #23
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    You are quite correct, when I modified my form based timer I removed the
    need for the delegate. Sorry for the confusion
    Because I don't pass any addresses to my own functions as delegates, I don't
    need to use a delegate at all.
    The function AddHandler takes a delegate as its second parameter, but the
    method address of the new timer handler can be passed in directly as one.
    A delegate would only be needed if we wanted to call back to the main class
    from the triggered TimerHandler, in which case we would create a delegate in
    Form1 and pass its value to the created TimerHandler so it knew where to
    call back to.

    Cheers,
    Jason

    "brandon" <brandonheng@hotmail.com> wrote in message
    news:3dbbe939@tnews.web.devx.com...
    > i went thru other examples on using delegates..
    >
    > eg,
    > Public Delegate Sub AddNodeDelegate(ByVal ShowText As String, ByVal Intg

    As
    > Integer, ByVal Strng As String, ByVal sts As Integer)
    >
    > TreeView1.BeginInvoke(New AddNodeDelegate(AddressOf AddPC), New Object()
    > {PcName, CInt(ID), RealID.ToString, 0})
    >
    > i am do not understand it 100%, but as i have seen, just like the example
    > above, i need to invoke the delegate, then specifying the function/sub to

    be
    > called..
    >
    > but in the example u gave, i do not see you doing that..
    >
    > AddHandler Timer2.Tick, AddressOf New TimerHandler("/" &
    > mynode.MyStrng).OnTimer1
    >
    > the delegate OnTimerHandler was not specified anywhere..
    >
    > please correct me if i am wrong.. but is there anything wrong with the
    > code?
    >
    >
    >
    >
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote in message
    > news:3dbb2694$1@tnews.web.devx.com...
    > > Look up 'delegates' in the help pages. It is basically a way of

    > specifying
    > > a template for callback functions.
    > > I'm not sure if there is some sort of inconsistency of bug in VS.Net,
    > > because you shouldn't be able to delete that line, and I had the same
    > > problem as you with the "does not have the same signature as delegate"

    > error
    > > when I was writing it. I suspect that the Delegate definition line is

    not
    > > always being freshly compiled.
    > >
    > > Cheers,
    > > Jason

    >
    >
    >




  9. #24
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote

    > Oh dear...
    > A hash table contains a key and an _object_, not a string!
    > A queue contains _only_ an object.


    > > By the time you create an object for the hash table and actually use it,
    > > you will have signifcantly more than the one line you show.



    > I would suggest you study up on the different
    > ADTs and their features, because you seem to be confusing a HashTable with
    > an Array.


    > > Take another look, your hashtable is a type of collection that implements 6
    > > different interfaces, the queue implements only half of those...



    > Check this out for more info:
    > http://www.aspfree.com/chapters/sams...234x_ch03.aspx


    "If you want objects stored and retrieved in the same order, use Queue" <...>
    "The fundamental behaviors of the collection classes are identical."



    >> Since the situation only calls for (and is trying to enforce) one
    >> outstanding request at any one time, why use a queue,


    >Because they would be in chronological order, making removal of old
    >requests a trival matter. (Enter a loop dequeuing the top object until an
    >object's time component is less than 10 seconds old)


    http://msdn.microsoft.com/library/en...ctionclass.asp
    <quote>
    Consider the following questions:

    a.. Do you need a sequential list where the element is typically discarded after its value is retrieved?
    a.. If yes, consider Queue or Stack.
    b.. If not, consider the other collections.
    </quote>

    HTH
    LFS




  10. #25
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    I thought you were done with this thread?

    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbc4c02$1@tnews.web.devx.com...
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    >
    > > Oh dear...
    > > A hash table contains a key and an _object_, not a string!
    > > A queue contains _only_ an object.

    >
    > > > By the time you create an object for the hash table and actually use

    it,
    > > > you will have signifcantly more than the one line you show.

    >
    >
    > > I would suggest you study up on the different
    > > ADTs and their features, because you seem to be confusing a HashTable

    with
    > > an Array.

    >
    > > > Take another look, your hashtable is a type of collection that

    implements 6
    > > > different interfaces, the queue implements only half of those...

    >
    >
    > > Check this out for more info:
    > > http://www.aspfree.com/chapters/sams...234x_ch03.aspx

    >
    > "If you want objects stored and retrieved in the same order, use Queue"

    <...>
    > "The fundamental behaviors of the collection classes are identical."


    Yes? And do we want the objects stored and retrieved in the same order? No


    > >> Since the situation only calls for (and is trying to enforce) one
    > >> outstanding request at any one time, why use a queue,

    >
    > >Because they would be in chronological order, making removal of old
    > >requests a trival matter. (Enter a loop dequeuing the top object until

    an
    > >object's time component is less than 10 seconds old)


    Thanks, this is exactly what I described as being _the only possible
    advantage of using a queue_, but when I typed in the code to do this, you
    implied I was writing unneccesary code.

    >

    http://msdn.microsoft.com/library/en...ctingcollectio
    nclass.asp
    > <quote>
    > Consider the following questions:
    >
    > a.. Do you need a sequential list where the element is typically

    discarded after its value is retrieved?
    > a.. If yes, consider Queue or Stack.
    > b.. If not, consider the other collections.
    > </quote>


    And is this the functionality we require? No.

    I know this might sound odd, but I do teach this stuff at university. I
    regularly have students arguing that their proposed solution is valid, but
    rarely do I have one arguing that recoding an inappropriate method into an
    appropriate one would be the best solution with such tenaciousness
    Perhaps you should code a solution to this problem? It would be a good
    exercise for us both (after all, I might be wrong).
    Since the main strength of OO development is reuse, and you seem confident
    that you can develop a solution quickly, please post a sample solution to
    this thread. I will do the same thing using a HashTable.
    As the OP stated, we have a list of nodes (we can ignore this detail), and
    he wants to prevent the user clicking on any node more often than, say,
    5secs. We could also prevent the user clicking unresponsive nodes more than
    every 10secs? That would be a nice sensible feature that shows the
    flexibility of a solution.
    So we have 2 functions required:
    1. Public Function Can_We_Send(MachineName as String) As Boolean
    2. Public Sub Response_Received(MachineName as String)

    Cheers,
    Jason



  11. #26
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    > I thought you were done with this thread?


    I didn't say anything, I copy and pasted text, but I can't refuse a (constructive) challenge...


    > I know this might sound odd, but I do teach this stuff at university.


    Oh, a real smart guy eh? (he he)

    > Perhaps you should code a solution to this problem? It would be a good
    > exercise for us both (after all, I might be wrong).
    > Since the main strength of OO development is reuse, and you seem confident
    > that you can develop a solution quickly, please post a sample solution to
    > this thread. I will do the same thing using a HashTable.


    OK, you're on...


    > As the OP stated, we have a list of nodes (we can ignore this detail), and
    > he wants to prevent the user clicking on any node more often than, say,
    > 5secs. We could also prevent the user clicking unresponsive nodes more than
    > every 10secs? That would be a nice sensible feature that shows the
    > flexibility of a solution.


    Now you want to change the problem? That's rather handy, since now I'd
    have some objects in the queue waiting for 10 seconds to elpase, and others
    after it waiting for 5 seconds to elapse.... In other words, your little change
    removes the sequential nature it orignally was in. No matter, as I said, any
    collection will do, and that's what I'll use, a standard collection.

    But, turnabout is fair play so I'll give you a small change. The debounce and
    pending delays were at 5 and 10 seconds respectively, but now, the response
    times are up in the neighborhood of 20-30 seconds. That's sensible is it not,
    you go out over the internet, and there is a little bit of a delay?

    Here's my solution using objects in a collection, I'm done before noon, can
    you get your hashtable working before the day ends?

    <g>
    LFS

    Public Class Ping
    Public Event Status(ByVal Note As String)
    Public DebounceSeconds As Integer
    Public PendingSeconds As Integer

    Private myPings As New Collection()
    Private myCounter As Long

    Public Class Pinger
    Public Enum PingStatus
    Ready
    Waiting
    Delayed
    Recieved
    End Enum

    Public Parent As Ping
    Public Name As String
    Public Sent As Date
    Public ID As Long
    Public Pending As PingStatus

    Public Sub New(ByVal Name As String, ByVal ID As Long, ByVal Parent As Ping)
    Me.Name = Name
    Me.ID = ID
    Me.Parent = Parent
    Me.Sent = Now
    Me.Pending = PingStatus.Waiting
    End Sub

    Public Overrides Function ToString() As String
    Return Name & ": " & ID.ToString
    End Function

    Public Sub DeadCall(ByVal DebounceSecs As Integer, ByVal PendingSecs As Integer)
    If Pending = PingStatus.Waiting Then
    If Now.Subtract(Sent).TotalSeconds >= PendingSecs Then
    Pending = PingStatus.Delayed
    End If
    ElseIf Pending = PingStatus.Recieved Then
    If Now.Subtract(Sent).TotalSeconds >= DebounceSecs Then
    Pending = PingStatus.Ready
    End If
    ElseIf Now.Subtract(Sent).TotalSeconds >= 180 Then
    Pending = PingStatus.Ready
    End If
    End Sub

    End Class


    Public Function Add(ByVal Name As String) As Pinger
    Dim i As Integer, Used As Pinger
    If myPings.Count > 0 Then
    For i = myPings.Count To 1 Step -1
    myPings(i).DeadCall(DebounceSeconds, PendingSeconds)
    If myPings(i).Pending = Ping.Pinger.PingStatus.Ready Then
    myPings.Remove(i)
    ElseIf Name = myPings(i).name Then
    If myPings(i).Pending = Ping.Pinger.PingStatus.Waiting _
    Or myPings(i).pending = Ping.Pinger.PingStatus.Recieved Then
    Used = myPings(i)
    End If
    End If
    Next
    End If

    If Used Is Nothing Then
    If myCounter < Long.MaxValue Then
    myCounter += 1
    Else
    myCounter = 1
    End If
    Dim p As New Pinger(Name, myCounter, Me)
    myPings.Add(p, p.ToString)
    RaiseEvent Status("SEND ping request to " & Name)
    Return p
    Else
    If Used.Pending = Ping.Pinger.PingStatus.Waiting Then
    RaiseEvent Status("Request to " & Name & " still pending")
    Else
    RaiseEvent Status("Repeat request to " & Name & " is too soon")
    End If
    End If
    End Function


    Public Sub Acknowlege(ByVal Request As Pinger)
    Dim p As Pinger, elapsed As TimeSpan
    Dim text As String
    For Each p In myPings
    If p.ID = Request.ID Then
    elapsed = Now.Subtract(p.Sent)
    text = elapsed.Seconds.ToString & "." & elapsed.Milliseconds.ToString
    RaiseEvent Status("ACK from " & p.Name & " response time = " & text & " sec.")
    p.Pending = Pinger.PingStatus.Recieved
    End If
    Next
    End Sub

    End Class





    Public Class Form1
    Inherits System.Windows.Forms.Form
    Private WithEvents myClientPings As New Ping()

    #Region " Windows Form Designer generated code "

    Public Sub New()
    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If Disposing Then
    If Not (components Is Nothing) Then
    components.Dispose()
    End If
    End If
    MyBase.Dispose(Disposing)
    End Sub

    Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
    Friend WithEvents ListBox2 As System.Windows.Forms.ListBox
    Friend WithEvents ListBox3 As System.Windows.Forms.ListBox
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.Container

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    Me.Label1 = New System.Windows.Forms.Label()
    Me.Label2 = New System.Windows.Forms.Label()
    Me.Label3 = New System.Windows.Forms.Label()
    Me.ListBox3 = New System.Windows.Forms.ListBox()
    Me.ListBox2 = New System.Windows.Forms.ListBox()
    Me.ListBox1 = New System.Windows.Forms.ListBox()
    Me.SuspendLayout()
    '
    'Label1
    '
    Me.Label1.Location = New System.Drawing.Point(14, 0)
    Me.Label1.Name = "Label1"
    Me.Label1.TabIndex = 0
    Me.Label1.Text = "Client"
    '
    'Label2
    '
    Me.Label2.Location = New System.Drawing.Point(163, 0)
    Me.Label2.Name = "Label2"
    Me.Label2.Size = New System.Drawing.Size(123, 15)
    Me.Label2.TabIndex = 3
    Me.Label2.Text = "Pending"
    '
    'Label3
    '
    Me.Label3.Location = New System.Drawing.Point(12, 160)
    Me.Label3.Name = "Label3"
    Me.Label3.Size = New System.Drawing.Size(104, 15)
    Me.Label3.TabIndex = 5
    Me.Label3.Text = "Status"
    '
    'ListBox3
    '
    Me.ListBox3.Location = New System.Drawing.Point(9, 183)
    Me.ListBox3.Name = "ListBox3"
    Me.ListBox3.ScrollAlwaysVisible = True
    Me.ListBox3.Size = New System.Drawing.Size(288, 121)
    Me.ListBox3.TabIndex = 2
    '
    'ListBox2
    '
    Me.ListBox2.Location = New System.Drawing.Point(159, 19)
    Me.ListBox2.Name = "ListBox2"
    Me.ListBox2.Size = New System.Drawing.Size(131, 134)
    Me.ListBox2.TabIndex = 3
    '
    'ListBox1
    '
    Me.ListBox1.Location = New System.Drawing.Point(11, 19)
    Me.ListBox1.Name = "ListBox1"
    Me.ListBox1.Size = New System.Drawing.Size(115, 134)
    Me.ListBox1.TabIndex = 4
    '
    'Form1
    '
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.ClientSize = New System.Drawing.Size(303, 317)
    Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.ListBox3, Me.ListBox2, Me.ListBox1, Me.Label3, Me.Label2,
    Me.Label1})
    Me.Name = "Form1"
    Me.Text = "Form1"
    Me.ResumeLayout(False)

    End Sub

    #End Region

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim i As Integer
    myClientPings.DebounceSeconds = 5
    myClientPings.PendingSeconds = 10
    For i = 1 To 5
    ListBox1.Items.Add("Machine " & i.ToString)
    Next
    End Sub

    Private Sub ListBox1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.Click
    If Not ListBox1.SelectedItem Is Nothing Then
    Dim p As Ping.Pinger
    p = myClientPings.Add(ListBox1.SelectedItem)
    If Not p Is Nothing Then ListBox2.Items.Add(p)
    End If
    End Sub

    Private Sub ListBox2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox2.Click
    If Not ListBox2.SelectedItem Is Nothing Then
    myClientPings.Acknowlege(ListBox2.SelectedItem)
    ListBox2.Items.Remove(ListBox2.SelectedItem)
    End If
    End Sub

    Private Sub Report(ByVal Msg As String) Handles myClientPings.Status
    ' Ping request and DB updating
    ShowMsg(Msg)
    Select Case Msg.Substring(0, 3)
    Case "SEN"
    ' Send Request
    ShowMsg("PING SENT to " & ListBox1.SelectedItem.ToString)
    Case "ACK"
    ' Update DB
    ShowMsg("DB Upated")
    End Select
    End Sub

    Private Sub ShowMsg(ByVal Msg As String)
    If ListBox3.Items.Count > 8 Then
    ListBox3.Items.RemoveAt(0)
    End If
    ListBox3.Items.Add(Msg)
    End Sub


    End Class




  12. #27
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    Hi Larry
    Good on you for joining in the fun!

    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbd7029@tnews.web.devx.com...
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote


    > > As the OP stated, we have a list of nodes (we can ignore this detail),

    and
    > > he wants to prevent the user clicking on any node more often than, say,
    > > 5secs. We could also prevent the user clicking unresponsive nodes more

    than
    > > every 10secs? That would be a nice sensible feature that shows the
    > > flexibility of a solution.

    >
    > Now you want to change the problem? That's rather handy, since now I'd
    > have some objects in the queue waiting for 10 seconds to elpase, and

    others
    > after it waiting for 5 seconds to elapse.... In other words, your little

    change
    > removes the sequential nature it orignally was in. No matter, as I said,

    any
    > collection will do, and that's what I'll use, a standard collection.
    >
    > But, turnabout is fair play so I'll give you a small change. The debounce

    and
    > pending delays were at 5 and 10 seconds respectively, but now, the

    response
    > times are up in the neighborhood of 20-30 seconds. That's sensible is it

    not,
    > you go out over the internet, and there is a little bit of a delay?


    Does it matter? Are you getting bogged down in irrelevancies?
    I don't think I changed any fundamental requirements, did I? I added one
    small thing just for fun, but it's basically the same. We could take that
    requirement out if you like

    > Here's my solution using objects in a collection, I'm done before noon,

    can
    > you get your hashtable working before the day ends?

    I can honestly say that I spent about 30mins working on this, and I posted
    it yesterday. Look under "Using Hash Tables (was Re: how to pass a variable
    to a timer's handler?)".
    I got back from work at 6:00pm, and after greeting the kids and making a cup
    of tea (I'm British, damnit) I was once again amazed at how easy it is to
    write something like this in VB.NET, and posted the finished thing (complete
    with test harness) at 7:22pm. You can see by its simplicity that there was
    not a great deal of coding to do, and (as the Ronseal advert says) "It does
    exactly wot it says on the can", meaning that it does exactly what was
    requested in the OP spec.
    It should be above this message in your reader.

    But Larry, you have not posted one using a Queue!!!! I don't understand!
    You told me that a queue would be the best solution to this problem, and
    there is no queue in your solution :/

    It's nice to see that you have used a HashTable in your solution though
    Take a look at the IL code generated in the Collection object:
    IL_0007: newobj instance void
    [mscorlib]System.Collections.Hashtable::.ctor()
    IL_000c: stfld class [mscorlib]System.Collections.Hashtable
    Microsoft.VisualBasic.Collection::m_HashData

    Yep, it is based on a HashTable.

    The whole point of this challenge was to allow you to justify using a Queue
    for the solution, so why did you use a Collection?

    It's all good fun though, so keep hacking

    Cheers,
    Jason


    > <g>
    > LFS
    >
    > Public Class Ping
    > Public Event Status(ByVal Note As String)
    > Public DebounceSeconds As Integer
    > Public PendingSeconds As Integer
    >
    > Private myPings As New Collection()
    > Private myCounter As Long
    >
    > Public Class Pinger
    > Public Enum PingStatus
    > Ready
    > Waiting
    > Delayed
    > Recieved
    > End Enum
    >
    > Public Parent As Ping
    > Public Name As String
    > Public Sent As Date
    > Public ID As Long
    > Public Pending As PingStatus
    >
    > Public Sub New(ByVal Name As String, ByVal ID As Long, ByVal

    Parent As Ping)
    > Me.Name = Name
    > Me.ID = ID
    > Me.Parent = Parent
    > Me.Sent = Now
    > Me.Pending = PingStatus.Waiting
    > End Sub
    >
    > Public Overrides Function ToString() As String
    > Return Name & ": " & ID.ToString
    > End Function
    >
    > Public Sub DeadCall(ByVal DebounceSecs As Integer, ByVal

    PendingSecs As Integer)
    > If Pending = PingStatus.Waiting Then
    > If Now.Subtract(Sent).TotalSeconds >= PendingSecs Then
    > Pending = PingStatus.Delayed
    > End If
    > ElseIf Pending = PingStatus.Recieved Then
    > If Now.Subtract(Sent).TotalSeconds >= DebounceSecs Then
    > Pending = PingStatus.Ready
    > End If
    > ElseIf Now.Subtract(Sent).TotalSeconds >= 180 Then
    > Pending = PingStatus.Ready
    > End If
    > End Sub
    >
    > End Class
    >
    >
    > Public Function Add(ByVal Name As String) As Pinger
    > Dim i As Integer, Used As Pinger
    > If myPings.Count > 0 Then
    > For i = myPings.Count To 1 Step -1
    > myPings(i).DeadCall(DebounceSeconds, PendingSeconds)
    > If myPings(i).Pending = Ping.Pinger.PingStatus.Ready Then
    > myPings.Remove(i)
    > ElseIf Name = myPings(i).name Then
    > If myPings(i).Pending = Ping.Pinger.PingStatus.Waiting

    _
    > Or myPings(i).pending =

    Ping.Pinger.PingStatus.Recieved Then
    > Used = myPings(i)
    > End If
    > End If
    > Next
    > End If
    >
    > If Used Is Nothing Then
    > If myCounter < Long.MaxValue Then
    > myCounter += 1
    > Else
    > myCounter = 1
    > End If
    > Dim p As New Pinger(Name, myCounter, Me)
    > myPings.Add(p, p.ToString)
    > RaiseEvent Status("SEND ping request to " & Name)
    > Return p
    > Else
    > If Used.Pending = Ping.Pinger.PingStatus.Waiting Then
    > RaiseEvent Status("Request to " & Name & " still pending")
    > Else
    > RaiseEvent Status("Repeat request to " & Name & " is too

    soon")
    > End If
    > End If
    > End Function
    >
    >
    > Public Sub Acknowlege(ByVal Request As Pinger)
    > Dim p As Pinger, elapsed As TimeSpan
    > Dim text As String
    > For Each p In myPings
    > If p.ID = Request.ID Then
    > elapsed = Now.Subtract(p.Sent)
    > text = elapsed.Seconds.ToString & "." &

    elapsed.Milliseconds.ToString
    > RaiseEvent Status("ACK from " & p.Name & " response time =

    " & text & " sec.")
    > p.Pending = Pinger.PingStatus.Recieved
    > End If
    > Next
    > End Sub
    >
    > End Class
    >
    >
    >
    >
    >
    > Public Class Form1
    > Inherits System.Windows.Forms.Form
    > Private WithEvents myClientPings As New Ping()
    >
    > #Region " Windows Form Designer generated code "
    >
    > Public Sub New()
    > MyBase.New()
    >
    > 'This call is required by the Windows Form Designer.
    > InitializeComponent()
    >
    > 'Add any initialization after the InitializeComponent() call
    >
    > End Sub
    >
    > 'Form overrides dispose to clean up the component list.
    > Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    > If Disposing Then
    > If Not (components Is Nothing) Then
    > components.Dispose()
    > End If
    > End If
    > MyBase.Dispose(Disposing)
    > End Sub
    >
    > Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
    > Friend WithEvents ListBox2 As System.Windows.Forms.ListBox
    > Friend WithEvents ListBox3 As System.Windows.Forms.ListBox
    > Friend WithEvents Label1 As System.Windows.Forms.Label
    > Friend WithEvents Label2 As System.Windows.Forms.Label
    > Friend WithEvents Label3 As System.Windows.Forms.Label
    >
    > 'Required by the Windows Form Designer
    > Private components As System.ComponentModel.Container
    >
    > 'NOTE: The following procedure is required by the Windows Form

    Designer
    > 'It can be modified using the Windows Form Designer.
    > 'Do not modify it using the code editor.
    > <System.Diagnostics.DebuggerStepThrough()> Private Sub

    InitializeComponent()
    > Me.Label1 = New System.Windows.Forms.Label()
    > Me.Label2 = New System.Windows.Forms.Label()
    > Me.Label3 = New System.Windows.Forms.Label()
    > Me.ListBox3 = New System.Windows.Forms.ListBox()
    > Me.ListBox2 = New System.Windows.Forms.ListBox()
    > Me.ListBox1 = New System.Windows.Forms.ListBox()
    > Me.SuspendLayout()
    > '
    > 'Label1
    > '
    > Me.Label1.Location = New System.Drawing.Point(14, 0)
    > Me.Label1.Name = "Label1"
    > Me.Label1.TabIndex = 0
    > Me.Label1.Text = "Client"
    > '
    > 'Label2
    > '
    > Me.Label2.Location = New System.Drawing.Point(163, 0)
    > Me.Label2.Name = "Label2"
    > Me.Label2.Size = New System.Drawing.Size(123, 15)
    > Me.Label2.TabIndex = 3
    > Me.Label2.Text = "Pending"
    > '
    > 'Label3
    > '
    > Me.Label3.Location = New System.Drawing.Point(12, 160)
    > Me.Label3.Name = "Label3"
    > Me.Label3.Size = New System.Drawing.Size(104, 15)
    > Me.Label3.TabIndex = 5
    > Me.Label3.Text = "Status"
    > '
    > 'ListBox3
    > '
    > Me.ListBox3.Location = New System.Drawing.Point(9, 183)
    > Me.ListBox3.Name = "ListBox3"
    > Me.ListBox3.ScrollAlwaysVisible = True
    > Me.ListBox3.Size = New System.Drawing.Size(288, 121)
    > Me.ListBox3.TabIndex = 2
    > '
    > 'ListBox2
    > '
    > Me.ListBox2.Location = New System.Drawing.Point(159, 19)
    > Me.ListBox2.Name = "ListBox2"
    > Me.ListBox2.Size = New System.Drawing.Size(131, 134)
    > Me.ListBox2.TabIndex = 3
    > '
    > 'ListBox1
    > '
    > Me.ListBox1.Location = New System.Drawing.Point(11, 19)
    > Me.ListBox1.Name = "ListBox1"
    > Me.ListBox1.Size = New System.Drawing.Size(115, 134)
    > Me.ListBox1.TabIndex = 4
    > '
    > 'Form1
    > '
    > Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    > Me.ClientSize = New System.Drawing.Size(303, 317)
    > Me.Controls.AddRange(New System.Windows.Forms.Control()

    {Me.ListBox3, Me.ListBox2, Me.ListBox1, Me.Label3, Me.Label2,
    > Me.Label1})
    > Me.Name = "Form1"
    > Me.Text = "Form1"
    > Me.ResumeLayout(False)
    >
    > End Sub
    >
    > #End Region
    >
    > Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As

    System.EventArgs) Handles MyBase.Load
    > Dim i As Integer
    > myClientPings.DebounceSeconds = 5
    > myClientPings.PendingSeconds = 10
    > For i = 1 To 5
    > ListBox1.Items.Add("Machine " & i.ToString)
    > Next
    > End Sub
    >
    > Private Sub ListBox1_Click(ByVal sender As Object, ByVal e As

    System.EventArgs) Handles ListBox1.Click
    > If Not ListBox1.SelectedItem Is Nothing Then
    > Dim p As Ping.Pinger
    > p = myClientPings.Add(ListBox1.SelectedItem)
    > If Not p Is Nothing Then ListBox2.Items.Add(p)
    > End If
    > End Sub
    >
    > Private Sub ListBox2_Click(ByVal sender As Object, ByVal e As

    System.EventArgs) Handles ListBox2.Click
    > If Not ListBox2.SelectedItem Is Nothing Then
    > myClientPings.Acknowlege(ListBox2.SelectedItem)
    > ListBox2.Items.Remove(ListBox2.SelectedItem)
    > End If
    > End Sub
    >
    > Private Sub Report(ByVal Msg As String) Handles myClientPings.Status
    > ' Ping request and DB updating
    > ShowMsg(Msg)
    > Select Case Msg.Substring(0, 3)
    > Case "SEN"
    > ' Send Request
    > ShowMsg("PING SENT to " & ListBox1.SelectedItem.ToString)
    > Case "ACK"
    > ' Update DB
    > ShowMsg("DB Upated")
    > End Select
    > End Sub
    >
    > Private Sub ShowMsg(ByVal Msg As String)
    > If ListBox3.Items.Count > 8 Then
    > ListBox3.Items.RemoveAt(0)
    > End If
    > ListBox3.Items.Add(Msg)
    > End Sub
    >
    >
    > End Class
    >
    >
    >




  13. #28
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote

    >
    > Does it matter? Are you getting bogged down in irrelevancies?
    > I don't think I changed any fundamental requirements, did I? I added one
    > small thing just for fun, but it's basically the same. We could take that
    > requirement out if you like


    I explained how your 'little change' modified the problem out of being a
    sequential problem. I could have done it with a queue, but you gave me a
    a different problem than was previously discussed so I 'used the right tool
    for the job'.

    >I was once again amazed at how easy it is to
    > write something like this in VB.NET, and posted the finished thing (complete
    > with test harness) at 7:22pm. You can see by its simplicity that there was
    > not a great deal of coding to do, and (as the Ronseal advert says) "It does
    > exactly wot it says on the can", meaning that it does exactly what was
    > requested in the OP spec.


    No it did not. The point was to 'debounce' the list (our term) to update the
    DB with the response time. You were the one saying to make a " _complete_
    solution" :

    <quote>
    Note that this is a _complete_ solution to the problem, and not just a section.
    </quote>

    But then you only supplied a section. If you ran my reply, which I can still
    use a queue for, if I want to shoehorn it in, you'll note it indicates exactly where
    to send the ping, and where to update the DB, and it shows the response time.

    > It's nice to see that you have used a HashTable in your solution though


    I don't know what kind of tricks you are pulling, I see no reference to my code
    in your disassembled example, however when I checked I saw this:

    //000007: Private myPings As New Collection()
    IL_0007: ldarg.0
    IL_0008: newobj instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Collection::.ctor()
    IL_000d: stfld class [Microsoft.VisualBasic]Microsoft.VisualBasic.Collection Challenge2.Ping::myPings
    IL_0012: ret


    I don't see any reference to a hashtable there....

    >
    > But Larry, you have not posted one using a Queue!!!! I don't understand!
    > You told me that a queue would be the best solution to this problem, and
    > there is no queue in your solution :/


    But, Jason, you haven't solved the problem! You told me you could do it using
    a hashtable. I see no response time indicated in your solution. ***???
    >
    > The whole point of this challenge was to allow you to justify using a Queue
    > for the solution, so why did you use a Collection?


    Because you changed the problem to make it less of a sequential problem. I can
    make a queue work in this scenareo, but since you changed the problem, I changed
    my recommendation to something more suited for the job. If you look back, I have
    been saying using an object in a collection will be better than a name/value pair which
    is what you first suggested. Halfway through the discussion you decided that maybe
    an object (with an extra Received property) would work better. Did you see me dangle
    that change out in front of you, and say, "Yep, you had to use an object in a collection"?

    Why didn't you solve the problem, you said you could use a hashtable to solve it, but
    you haven't shown the response time yet. And, keep in mind, you don't know when the
    response will come in.

    LFS







  14. #29
    Jason Sobell \(iGadget\) Guest

    Re: how to pass a variable to a timer's handler?

    "Larry Serflaten" <serflaten@usinternet.com> wrote in message
    news:3dbdd12e@tnews.web.devx.com...
    > "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote
    >
    > >
    > > Does it matter? Are you getting bogged down in irrelevancies?
    > > I don't think I changed any fundamental requirements, did I? I added one
    > > small thing just for fun, but it's basically the same. We could take

    that
    > > requirement out if you like

    >
    > I explained how your 'little change' modified the problem out of being a
    > sequential problem. I could have done it with a queue, but you gave me a
    > a different problem than was previously discussed so I 'used the right

    tool
    > for the job'.


    Show me where you explained this? You claimed that the .Contains method
    addressed this efficiently. I don't have to cut and paste your comments to
    this effect, but take the time to browse back through this thread.
    As I said, take that requirement out and show me a solution using a queue.

    > >I was once again amazed at how easy it is to
    > > write something like this in VB.NET, and posted the finished thing

    (complete
    > > with test harness) at 7:22pm. You can see by its simplicity that there

    was
    > > not a great deal of coding to do, and (as the Ronseal advert says) "It

    does
    > > exactly wot it says on the can", meaning that it does exactly what was
    > > requested in the OP spec.

    >
    > No it did not. The point was to 'debounce' the list (our term) to update

    the
    > DB with the response time. You were the one saying to make a " _complete_
    > solution" :


    Update the DB with the response time? What are you talking about?
    "user(from server) may click the client's info from treeview and it will
    send
    a request to client.. asking for the updated info.. then update the central
    database..
    problem is we dun wan the user( from server) to send the request many times,
    when the user starts clicking.. right? so, i set a timer on the treeview
    afterselect.."

    You seem to be altering the original requirements to justify every change
    you make and support all your misunderstandings.

    > <quote>
    > Note that this is a _complete_ solution to the problem, and not just a

    section.
    > </quote>
    >
    > But then you only supplied a section. If you ran my reply, which I can

    still
    > use a queue for, if I want to shoehorn it in, you'll note it indicates

    exactly where
    > to send the ping, and where to update the DB, and it shows the response

    time.

    None of which was requested.

    > > It's nice to see that you have used a HashTable in your solution though


    >
    > I don't know what kind of tricks you are pulling, I see no reference to my

    code
    > in your disassembled example, however when I checked I saw this:
    >
    > //000007: Private myPings As New Collection()
    > IL_0007: ldarg.0
    > IL_0008: newobj instance void

    [Microsoft.VisualBasic]Microsoft.VisualBasic.Collection::.ctor()
    > IL_000d: stfld class

    [Microsoft.VisualBasic]Microsoft.VisualBasic.Collection
    Challenge2.Ping::myPings
    > IL_0012: ret
    >
    >
    > I don't see any reference to a hashtable there....


    Unfortunately you are just reinforcing your ignorance of the workings of
    ..NET :/
    Go to the framework directory (normally
    %windir%\Microsoft.NET\Framework\v1.0.3705) and open
    "Microsoft.VisualBasic.dll"
    This contains the source for the Collection, and you will find it in there.
    Quote: "You got to learn to think outside the box... <g>"

    > >
    > > But Larry, you have not posted one using a Queue!!!! I don't

    understand!
    > > You told me that a queue would be the best solution to this problem, and
    > > there is no queue in your solution :/

    >
    > But, Jason, you haven't solved the problem! You told me you could do it

    using
    > a hashtable. I see no response time indicated in your solution. ***???
    > >
    > > The whole point of this challenge was to allow you to justify using a

    Queue
    > > for the solution, so why did you use a Collection?

    >
    > Because you changed the problem to make it less of a sequential problem.

    I can
    > make a queue work in this scenareo, but since you changed the problem, I

    changed
    > my recommendation to something more suited for the job. If you look back,

    I have
    > been saying using an object in a collection will be better than a

    name/value pair which
    > is what you first suggested. Halfway through the discussion you decided

    that maybe
    > an object (with an extra Received property) would work better. Did you

    see me dangle
    > that change out in front of you, and say, "Yep, you had to use an object

    in a collection"?

    If you look back at the thread you will see that I never even implied that I
    would not use an object. If the 'lack of response extended debounce' code
    was removed then an extra object is not required at all, but this is a
    pointless and irrelevant argument.

    I recently read someone's sig on my local news server which read "Never
    argue with an idiot; He will drag you down to his level and beat you with
    experience", and while I don't suggest you are an idiot, I do suggest that
    you need a great deal more experience in understanding ADTs and applying
    them.

    You have introduced this bizzare requirement for a response time to justify
    your completely irrelevant arguments, and I have had enough.
    Hopefully someone will find some use for the code we posted, and I'm sure
    many more people are amused by the futility of this discussion, but every
    time I have asked a question you have responded with something irrelevant.
    Your suggestion for using a queue was valid but a poor choice, and since
    being asked to support your argument you have painted yourself into a corner
    then managed to twist the whole thing around, showing that you have
    suprisingly little experience of applying solutions to real-world scenarios.

    Jason

    > Why didn't you solve the problem, you said you could use a hashtable to

    solve it, but
    > you haven't shown the response time yet. And, keep in mind, you don't

    know when the
    > response will come in.
    >
    > LFS




  15. #30
    Larry Serflaten Guest

    Re: how to pass a variable to a timer's handler?

    "Jason Sobell (iGadget)" <iGadget_@hotmail.com> wrote

    > > I explained how your 'little change' modified the problem


    >
    > Show me where you explained this?


    It certainly wasn't back in the original discussion which must have been
    where you were looking. See the message posted Mon at 11:23am. The one
    containing my posted solution.


    > You claimed that the .Contains method
    > addressed this efficiently. I don't have to cut and paste your comments to
    > this effect, but take the time to browse back through this thread.


    Trying to nit pick details, eh? You are way off base, I never said the .Contains
    method was efficient, I said using a queue could be easily done.

    > As I said, take that requirement out and show me a solution using a queue.


    OK, soon after you show a full solution using a hashtable.

    > Update the DB with the response time? What are you talking about?


    My slip, in the heat of the moment. Updated information has a time element.
    In this case that element was not defined, it was the updated information that
    needed to go to the DB. Sending multiple requests could 'very easily' return
    different results, or return nothing at all. Without keeping track of the response
    time you have no idea how current those results are. You have focused on a
    minute aspect of the problem (debouncing) without taking the whole
    implementation into consideration. I saw that early on and told you that table
    is not forward looking.


    > "user(from server) may click the client's info from treeview and it will send
    > a request to client.. asking for the updated info.. then update the central
    > database..
    > problem is we dun wan the user( from server) to send the request many times,
    > when the user starts clicking.. right? so, i set a timer on the treeview
    > afterselect.."
    >
    > You seem to be altering the original requirements to justify every change
    > you make and support all your misunderstandings.


    You're the who altered the problem with 'a little change'. Where does he say
    he needed two different debounce times?


    > > > It's nice to see that you have used a HashTable in your solution though

    > >
    > > I don't see any reference to a hashtable there....

    >
    > Unfortunately you are just reinforcing your ignorance of the workings of
    > .NET :/
    > Go to the framework directory...
    > Quote: "You got to learn to think outside the box... <g>"


    That wasn't my code, I used a collection. The fact that MS wraps a collection
    around a hashtable and arraylist does not effect the code I wrote. That's
    called encapsulation, a black box is a black box. Since you didn't recognize it
    for what it is, that must mean you are woefully ignorant of the OOP paradigm!


    > Your suggestion for using a queue was valid but a poor choice, and since
    > being asked to support your argument you have painted yourself into a corner
    > then managed to twist the whole thing around, showing that you have
    > suprisingly little experience of applying solutions to real-world scenarios.


    It does little good to suggest a solution without making sure the implementation
    is possible. You suggested you would use a keyed pair and I suggested using
    a queue (collection) of objects. At that time both would work, and I indicated
    as much, but then you challenged my suggestion. In the insuing discussion,
    you changed the problem, and jumped on me for changing the requirements.

    I provided a working solution, that showed exactly where to send the request,
    and where to update the DB, and would handle the debouncing issue. You
    provided code to handle a limited debouncing scenareo and called it a
    complete solution. Finally, instead of following up with a complete solution,
    you say I twisted it all around an have little experience with 'real-world' scenarios.
    With what you suggested, I'd bet you've got a chronic case of not-my-job
    syndrom.

    Now wasn't that entertaining....
    LFS




Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center