Results 1 to 5 of 5

Thread: Threading - Add a 1 second delay between calls

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Threading - Add a 1 second delay between calls

    Hi,

    I am sending commands to some server via an UdpClient. However, I need to make sure that all commands send are separated by a 1 second delay. If there is no delay, two commands send within this 1 second timespan will not be received both; only the first or the second command will get through.

    The commands are sent in a background thread at the moment, because it might take some time before the command is sent. I keep looping until the command has been sent, like this:
    vb.net Code:
    1. Public Sub Send(command As String)
    2.     Dim bytes = Me.GetCommandBytes(command)
    3.    
    4.     Dim t As New Thread(ThreadSend)
    5.     t.Start(bytes)
    6. End Sub
    7.  
    8. Private Sub ThreadSend(commandBytes As Object)
    9.     Dim bytes = DirectCast(commandBytes, Byte())
    10.    
    11.     Dim sent = False
    12.     While Not sent
    13.         Me.Client.Send(bytes, bytes.Length, _IpEndPoint)
    14.         Thread.Sleep(200)
    15.         If Me.Client.Available > 0 Then
    16.             sent = True
    17.         End If
    18.     End While
    19. End Sub

    This does not keep into mind the 1 second delay though. When I send four commands consecutively, like:
    Code:
    Send("test1")
    Send("test2")
    Send("test3")
    Send("test4")
    The results seem a little random, but I never get them all. Sometimes just 1, sometimes 1 and 3, sometimes 2 and 3, sometimes even 4 and then 1

    I have reason to believe that the 1 second delay will fix this (if not, well, then I'm clueless, but I'm sure you are as well so there's no point in asking).


    I'm not sure how to build this delay however. Simply adding a Thread.Sleep(1000) in the ThreadSend method won't work of course; the four commands sent consecutively will all wait one second and then still be sent (nearly) at the same time. There needs to be a delay between commands, not before commands.


    I am thinking I need some kind of Queue which I fill with the commands in the Send method. Then another thread is constantly looping through this Queue, in one second intervals, and sending the first command (if one is available).

    However, I have a feeling something like this should be easier. I have heard about the ThreadPool before, which sounds like it might do what I want already, but I have no clue how to use it. The thing is: the ThreadPool seems to fire off as many threads as it can before it queues up new threads; and it handles those new threads as soon as they are available, which is not what I want at all.



    Any ideas?

  2. #2
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Threading - Add a 1 second delay between calls

    I would use a queue - it's something that this class was designed for:

    vb Code:
    1. Public Class Form1
    2.  
    3.     Private msgQueue As New Queue(Of String)
    4.     Private qMgr As Threading.Thread
    5.  
    6.     Private Sub Send(ByVal text As String)
    7.         msgQueue.Enqueue(text)
    8.     End Sub
    9.  
    10.     Private Sub QueueManager()
    11.         Do
    12.             Threading.Thread.Sleep(1000)
    13.             If msgQueue.Count > 0 Then
    14.                 Dim str As String = msgQueue.Dequeue()
    15.  
    16.                 'send string here
    17.             End If
    18.         Loop
    19.     End Sub
    20.  
    21.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    22.         qMgr = New Threading.Thread(AddressOf QueueManager)
    23.         qMgr.Start()
    24.     End Sub
    25. End Class

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Threading - Add a 1 second delay between calls

    Yeah, that is similar to what I'm going with now. Mine is a little more complicated, I can stop the queue reading when I want to (and it's stopped neatly when the application closes of course), but I don't have that much experience with threading and I'm afraid I might run into cross-threading errors or something like that. I was just wondering if there was something built in (ThreadPool for example) which handles everything gracefully for me.

  4. #4
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Threading - Add a 1 second delay between calls

    Is there some delay on the receiving end?
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  5. #5
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Threading - Add a 1 second delay between calls

    Quote Originally Posted by NickThissen View Post
    I'm afraid I might run into cross-threading errors or something like that. I was just wondering if there was something built in (ThreadPool for example) which handles everything gracefully for me.
    Unless you overcomplicated this example, there shouldn't be any issues.
    Well then, if you're worried, you can synclock/unlock your queue while it is being modified.

    As for 'handles everything gracefully' - I don't think they at Microsoft did that much. You have to always cross your fingers when you do into multithreading.
    One queue and two threads shouldn't cause any problems though.

Posting Permissions

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



Click Here to Expand Forum to Full Width