07-18-2007, 06:56 PM
hi there !!
I'm running a software that is running in a while process waiting for responds from the user or a predefine set time that will occure something.
I'm using the sleep function (10 miliseconds) not to make the while halt the computer. (i think this is not the best way to do it, but it's the best way i could do it :-(
I getting some data form a serial port and i want to get it updated every two seconds in a text box of the screen
The thing is that while i'm waiting for something to happen i want to updated some data on the screen every two seconds
Hope i made my self clear....Can someone help me please?
ouh, and one more question, sometimes i would like to be able to halt all the inputs form the user during some time(mouse inputs) to not interfiere with the software. Is this possible?
Here is part of the code
If Now > sig_evento.fecha Then
'do some things.....
Application.DoEvents() 'for letting the software catch the inputs from the user
Threading.Thread.Sleep(10)'for not halting the computer
tmp_sala_calderas.Text = var 'put data from serial port in a text box
The problem is that i do not need to updated the data every 10 miliseconds, but i don't want to continuosly halt the system for two seconds
07-18-2007, 07:10 PM
i found a simple way(actually i think it was simple ;-)
i putted this into the while
If Now > DateAdd(DateInterval.Second, 2, aaa) Then
aaa = Now
Just two things remaining:
I'm using the sleep function (10 milliseconds) not to make the while halt the computer. (i think this is not the best way to do it, but it's the best way i could do it :-(
And the other:
ouh, and one more question, sometimes i would like to be able to halt all the inputs form the user during some time(mouse inputs) to not interfere with the software. Is this possible?
help much appreciated
07-19-2007, 09:28 AM
If you are running your code in a while loop, you need to make the loop hault for x period of time if you want to give some lee-way between checks. Thread.Sleep would work, but rememeber this makes the CURRENT thread sleep..so if you are running this on your main WinForm STA thread for example, that will pause all execution. If you run this code within a seperate thread, that thread will wait for the x duration and your main STA thread will still be processing messages. Really depends on your requirements. You wouldn't have to use Thread.Sleep per say, you could also use a AutoResetEvent call the WaitOne() method, either passing a duration to pause, or wait for the AutoReset Event to invoke the .Set() method which would unblock it.
The Kernel WaitHandle events are documented on MSDN, do a search or if you have a specific question after trying to dig into this, let us know.
Regarding "haulting" the computer in relation to mouse inputs, it depends on what you want to do. So you want to pause execution until the user clicks the mouse 10 times for example? If so, within the Mouse Down event or one of the similiar mouse events (would depend on what action you want to wake up) you would have to use a counter or integer that ++ on each event. After a specific number of iterations you would unblock or continue the "other" execution that you want to do (and maybe handle or cancel the last Mouse click, not sure what you want to do :) )
07-19-2007, 11:08 AM
Here's a small example of how you could use ThreadPool's RegisterWaitForSingleObject to set up a "wait x seconds" loop that doesn't block your UI. Put it on a form that has a TextBox named txtOutput, a button named btnStart, and a button named btnStop:Imports System.Threading
Public Class Form1
Private _cancelSignal As AutoResetEvent = New AutoResetEvent(False)
Private _operationHandle As RegisteredWaitHandle
Private Sub StartThread()
Debug.WriteLine("StartThread from " & Thread.CurrentThread.ManagedThreadId)
Dim contextObject As AsyncOperation = AsyncOperationManager.CreateOperation(Nothing)
_operationHandle = ThreadPool.RegisterWaitForSingleObject(_cancelSignal, New WaitOrTimerCallback(AddressOf WorkItemCallback), contextObject, TimeSpan.FromSeconds(3), False)
Private Sub WorkItemCallback(ByVal userState As Object, ByVal timedOut As Boolean)
Dim operation As AsyncOperation = TryCast(userState, AsyncOperation)
If operation Is Nothing Then
Throw New ArgumentException("I expected an AsyncOperation!")
' timeout means we want to execute; if we have signaled then we want to cancel
If timedOut Then
operation.Post(New SendOrPostCallback(AddressOf UpdateControls), "Working!")
operation.Post(New SendOrPostCallback(AddressOf UpdateControls), "Cancelled!")
' VERY IMPORANT!
Private Sub UpdateControls(ByVal userState As Object)
Dim message As String = TryCast(userState, String)
If message IsNot Nothing Then
txtOutput.Text = message
txtOutput.Text = "Whoops!"
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
btnStart.Enabled = False
btnStop.Enabled = True
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
_btnStop.Enabled = False
_btnStart.Enabled = True
End ClassDO NOT do like I initially did and forget about AutoResetEvent and use ManualResetEvent instead; the result causes the method to get called several times before it is unregistered.
Here's the basic theory:
StartThread() kicks the process off by calling ThreadPool's RegisterWaitForSingleObject method, specifying a WaitHandle, callback method, timeout period, and that the method should execute repeatedly. We hold on to the return value since we need it to tell Windows when to stop running the operation. Also notice the AsyncOperation I create; this is used later to make sure function calls occur on the right thread. For now, I package it as the userState argument to RegisterWaitForSingleObject.
The next part happens in la-la-land. Either the operation times out or _cancelSignal is set; when either happens WorkItemCallback is called with the appropriate timedOut parameter. The first thing to do is unpackage the AsyncOperation and die if it isn't what I expect. This is actually not best practice because there's no way for user code to catch and handle this exception; the IAsyncResult pattern or the Event-Based Asynchronous Pattern are documented well on MSDN and handle this better and could be worked into this but for simplicity I did not. Anyway, the next thing we do is determine if WorkItemCallback was called due to timeout or because the WaitHandle was set. If it timed out the AsyncOperation is used to send a message to the UI thread; if the WaitHandle was set we send a message to the UI thread then unregister our ThreadPool operation so it will stop happening.
UpdateControls simply updates the TextBox. The only thing of note here is since it was called via AsyncOperation.Post it will always be called on the UI thread.
The start button handler updates the state of the buttons then calls StartThread(). The stop button handler updates the buttons and signals our AutoResetEvent, which causes the ThreadPool thread to call WorkItemCallback with a timedOut value of False.