Jump to content

How to allow event to interrupt during spinning?

- - - - -

  • Please log in to reply
7 replies to this topic

#1
yopie

yopie

    Newbie

  • Members
  • Pip
  • 2 posts
I'm a newbie working on a project, and need some help to interact with a device through serial port.

Now I'm sending command which wait for a reply from the device. The command is in a method as follow:

do
{
if (Application.MessageLoop)
Application.DoEvents();
}
while(!boolReplyReceived)

boolReplyReceived is changed by event handler, which is triggered upon receiving data from serial port.

My problem is, the DoEvents() does many things and therefore the single iteration takes a few seconds. I read many recommendation to avoid DoEvents() and use AutoResetEvent instead, but still, if I put WaitOne() at the above loop, how will I be able to put the set() in the event handler, since the event will never be triggered when the main UI thread is blocking? In other words, how do I cause the event handler to run on a worker thread, so that it can still receive data on main thread blocking?

To illustrate, if I change to the following, the UI will freeze:

in the main UI thread:

_waitHandle.WaitOne();

in the event handler:

onDataReceived()
{
_waitHandle.set()
}


Any help is much appreciated. :)

#2
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
What do you mean DoEvents does many things? It's designed to execute Windows messages in window procedure, which is basically doing GUI operations and timers - that must never include "many things". If it does, then your design is bad. For example, if you're fetching data from database or filling enormously large lists, etc. from window procedure.

#3
Momerath

Momerath

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 242 posts
You'll also want to read Threading in C#

#4
yopie

yopie

    Newbie

  • Members
  • Pip
  • 2 posts
@ Zoranh, Thank you for making me think about this point. Well, this 'many things' is necessary because the UI I'm working with keep refreshing the ImageBox since I'm displaying a video, whereby an event handler keeps refreshing the form with new image at 25Hz or so.

@ Momerath, Been reading it for sometime, and still not able to fit the threading concept into event concept. How do I cause the event handler to run on another thread, and therefore it can be triggered at anytime even when the main thread is blocking (or spinning)?

#5
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
Working from another thread will not help you in that application. That's because you can't update picture on the form from a different thread. So even if you use another thread, that thread would only make an asynchronous call to a method which changes the picture from within the form thread, for instance by using Form.BeginInvoke method.

Anyway, there's no good answer to your question because simulating video by swapping picture on the form at 25 Hz is not efficient, and any efficient way is far more complex to code than that...

#6
Momerath

Momerath

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 242 posts

yopie said:

@ Zoranh, Thank you for making me think about this point. Well, this 'many things' is necessary because the UI I'm working with keep refreshing the ImageBox since I'm displaying a video, whereby an event handler keeps refreshing the form with new image at 25Hz or so.

@ Momerath, Been reading it for sometime, and still not able to fit the threading concept into event concept. How do I cause the event handler to run on another thread, and therefore it can be triggered at anytime even when the main thread is blocking (or spinning)?

What 'many things' is it doing? If the main thread is blocking, move that code to a different thread so it doesn't block your UI.

#7
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts

Momerath said:

What 'many things' is it doing? If the main thread is blocking, move that code to a different thread so it doesn't block your UI.
It's not that simple. .NET allows UI operations only from main thread. So raising another thread doesn't solve the problem, because that thread would have to bounce UI operations back to main thread anyway.

The only benefit could be if there are other operations before UI is updated, e.g. loading data from database or file, reading from socket, etc. In those cases another thread is definitely required, so that main thread can be saved only to update controls, once content is fully prepared by the worker thread.

#8
Momerath

Momerath

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 242 posts

zoranh said:

It's not that simple. .NET allows UI operations only from main thread. So raising another thread doesn't solve the problem, because that thread would have to bounce UI operations back to main thread anyway.

The only benefit could be if there are other operations before UI is updated, e.g. loading data from database or file, reading from socket, etc. In those cases another thread is definitely required, so that main thread can be saved only to update controls, once content is fully prepared by the worker thread.
It really depends on what those 'other things' are, doesn't it? If he's loading images and processing them for display, he can do this in another thread, no reason that the UI thread has to do pre-processing of the images. It could store them in some form of data structure and the UI thread pull them out when it needs them (Queue seems applicable).

There isn't enough information given to determine if threading will help, but I suspect it could if designed right :)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users