-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
>
>
>
-
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
-
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
-
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
-
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
>
>
>
-
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
-
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
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks