Re: Alternatives to Application.DoEvents?
- From: "Charles Law" <blank@xxxxxxxxxxx>
- Date: Mon, 1 Aug 2005 10:38:59 +0100
Hi John
You seem to be describing exactly a situation I had to code for a little
while ago. The solution I went for was to use the Monitor class.
The logic is this:
Send command to remote serial device on main thread.
Call function WaitForReply to block main thread until response received or
time-out.
WaitForReply is coded thus:
<code>
Private m_ResponseReceived As Object = New Object
Private Function WaitReply(ByVal timeout As Integer) As Boolean
SyncLock m_ResponseReceived
If Monitor.Wait(m_ResponseReceived, timeout) Then
Return True
Else
Return False
End If
End SyncLock
End Function
</code>
Now, there is an event that is raised when serial data is received. In this
event, I check what has been received and when I have a complete reply, I
call ResponseReceived, below.
<code>
Private Sub ResponseReceived()
SyncLock m_ResponseReceived
' Pulse this object, which any waiting thread will be attempting
' to get a lock on.
Monitor.Pulse(m_ResponseReceived)
End SyncLock
End Sub
</code>
That's it. The main thread is blocked until a response is received or there
is a time-out. The cpu does not go off the scale, and everything is nice and
responsive so long as the value of timeout is quite small.
HTH
Charles
"TrtnJohn" <TrtnJohn@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:AADBF45C-483B-4880-91B6-624F7B1E3D83@xxxxxxxxxxxxxxxx
> Tom,
>
> That makes good sense. But, let me explain why I have problems with that
> approach and why I am trying to keep the methods synchronous. There are
> actually many different types of commands to the device with many
> different
> functions, parameters and return data. I want to hide all that and just
> let
> the application perform simple requests. Each application request may
> execute many different commands to the device. The command sequence and
> logic is controlled by a number of factors. These include: The initial
> application request, parameters from the initial application request, and
> the
> return data from each individual command. If I make a CommandResponse
> event
> I'll need to keep a ton of globals to manage the state of each request.
> If I
> make the commands synchronous I can implement each application request
> using
> flow control within the method instead of relying on global state
> variables.
> For example:
>
> Public Sub AppRequest1(Byval Param as String)
> If Device.Command1 = Success Then
> CurStatus = Device.Command2(Param)
> Return Device.Command3(CurStatus)
> Else
> Device.Command4(Param)
> End If
> End Sub
>
> As you see, if I used events for every command completion and tried to
> implement similar logic as the sample above would require a lot of global
> state variables. And, the problem grows exponentially depending on how
> many
> different application requests and commands I have.
>
>
>
> "Tom Shelton" wrote:
>
>> On 2005-07-30, TrtnJohn <TrtnJohn@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>> > I am not sure that asynchronous methods will give me the behavior I am
>> > looking for. I want the original call to NOT return to the caller
>> > until the
>> > async method completes. While the original call is blocked I want
>> > windows
>> > messages to still be processed. Unless I am misunderstaning things, I
>> > would
>> > still have to poll the status of the async method in order to block
>> > waiting
>> > for it to complete. I may as well use DoEvents in that case. Here's a
>> > few
>> > more details about the problem:
>> >
>>
>> No... An async method can call a callback when it is completed. You can
>> pass the callback to the BeginInvoke method of the delegate. In other
>> words, you don't really need to do a separate thread (well, not
>> explicitly - async methods are called on a separate thread).
>>
>>
>> > The application I am working talks to a serial device. The main thread
>> > sends requests and the secondary thread reads responses. Once a
>> > request is
>> > sent I want to block until a response is received or timeout occurs.
>> > During
>> > this wait time I do not want the UI to go unresponsive. Basically, I
>> > am
>> > trying to hide the fact that commands to this device requires a
>> > request/response and wrap them into a single synchronous method call
>> > for
>> > higher level objects to use.
>>
>> I wouldn't do it that way... I would expose this as events. Something
>> like a commandcomplete event. Then the main thread calls the method and
>> returns - there for remains responsive - though, you might have to lock
>> the user out of certain gui functions until the work is done. The class
>> wraps the thread and the async delegate calls, and when it gets it's
>> result,
>> raises an event back to the main form.
>>
>> Make sense?
>>
>>
>> --
>> Tom Shelton [MVP]
>>
.
- Follow-Ups:
- Re: Alternatives to Application.DoEvents?
- From: TrtnJohn
- Re: Alternatives to Application.DoEvents?
- References:
- Re: Alternatives to Application.DoEvents?
- From: Ken Tucker [MVP]
- Re: Alternatives to Application.DoEvents?
- From: TrtnJohn
- Re: Alternatives to Application.DoEvents?
- From: Tom Shelton
- Re: Alternatives to Application.DoEvents?
- From: TrtnJohn
- Re: Alternatives to Application.DoEvents?
- Prev by Date: Re: Dealing with a group of Timers
- Next by Date: Re: Dealing with a group of Timers
- Previous by thread: Re: Alternatives to Application.DoEvents?
- Next by thread: Re: Alternatives to Application.DoEvents?
- Index(es):
Relevant Pages
|