I want to make a program that runs in Windows using dialog boxes and such, but
unlike applications like calculator that sit and wait for you to do something,
I want something more like media player that plays but still lets you use the
controls.
The getmessage function doesn't move on until it gets a message, so I can't
use that standard pump if I want to make a program that is actively doing
something in the background.
Do I need to make a multi-thread program where one thread handles the window
elements and one thread runs the program?
What my program will do is monitor a certain directory and when there are
files added to the directory, it will process them and send them key by key to
an external system. But while it is doing that I want to be able to have watch
windows, menus, etc.
What are your thoughts?
-Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I can think of three solutions; two of them general, and one specific to your
particular problem (and probably the best solution in this case).
The general solutions are:
1) Create a worker thread to perform the activity concurrently to the message
handling procedure.
2) Use a timer to periodically sent WM_TIMER messages to your message handling
procedure and do a 'bit of work' on each event. In this case simply check the
folder you are monitoring.
Method 1 is a bit heavyweight for this particular task, where method 2 would
be more appropriate. However there is another method which is probably better
still. The operating system can watch for file system events for you and send
messages to your message handler when they occur. This is how tools such as
Google Desktop work - only indexing files when they change. In .NET this is
easily achieved using the . I am sure I have seen this done in plain Win32,
but cannot immediately find the appropriate API.
Thank you, that's pretty much what I was thinking was either a concurrent
thread or a timer... I was just hoping maybe there is some sort of an
alternate command to getmessage that instead of waiting would fall through and
let me do other things. However, if theoretically there was something like
that, I would still have to break the program down into little pieces and have
it do a small portion and come back to check the message queue again,
otherwise the window controls would lag considerably. Therefore, in theory a
timer is pretty much the same thing, just perhaps not quite as tight because
depending on how long I go between calls, there could be unused time. I'll
play with it, until I have a program complicated enough to need a worker
thread and then I will see how that works.
Interesting to think about just how many programs in Windows really do just
sit and wait... it was hard for me to think of an example of a program that
doesn't.
As far as checking for the file, I will do some research and see if I can find
something I can use in Dev, or I can just have part of the timer loop be
looking... I will still need a timer either way because once the file is found
and it begins the process of processing and exporting, it could be a lengthy
process so I would still need the system to be able to do the window calls as
well. Eventually, I want to be able to do COM support in and out and plug-ins
too so I'll take it all into consideration.
-Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Having GetMesage() fall through detrimentally would affect the performance of
other programs running on your machine by hogging a large number of CPU
cycles. In old 16 bit versions of Windows that used cooperative multi-tasking,
it would haveground everything else to a halt by taking all cycles outside
of interrupt handlers. Even with pre-emptive multi-tasking, the Windows
scheduler expects applications to behave responsibly, and continuously using
all the available time-slice will affect other processes that might otherwise
run.
However, should wou wish to do that it is easily done. You can call , and then
only call GetMessage() to clear the queue is there is a message available;
this effecting a non-blocking message handler.
It is a rather inelegant solution however. Threads are not difficult to use
(although again much simpler in .NET - the Win32 API suffers from the weight
of its legacy, and the fact that it is not object oriented).
Thanks... I am concerned about not hogging all the CPU's resources, I do want
my programs to "play nice" so I'll keep that in mind, if there comes
a critical part that has to be done with tight timing, I suppose I could try
the peekmessage command, but then again if it is that critical of an operation
I probably don't need to worry about menus and windows, etc. because the
operation itself would be more important.
I was hoping even doing a timer wouldn't tie up my computer too much, if I did
it for every half a second or something. I haven't tried it yet, I am still
planning. I will probably use multi-threading when all the pieces come
together... start with a timer and then as I add pieces I will change the
timer to a thread and have flags, like a state machine, to coordinate all the
pieces. Then when I add COM support (I want to be able to query the status of
my program from VBA, because the majority of the files to process will come
from Excel), that will probably be its own thread as well.
I am just used to programming DOS-style, where I get to control everything...
but I have to let go a little and let Windows help me.
Now I see all my options on the table, I can play around a bit.
-Dan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Even very rapid timer event messages (say 50 to 100 per second) would not in
themselves trouble a modern CPU, it is rather how much work you do in each
event that would be critical. For example is you had a timer event every 100ms
and the processing took 90ms, that would be 90% of the CPU dedicated to your
task. If you are watching for file or folder changes the polling rate would be
determined entirely on how soon after such an event you need your program to
react.
Either way, the Windows Task Manager will tell you teh total CPU load and teh
specific load for individual processes. Use that to check the behaviour of
your program. On the processes list you can add all sorts of additional
metrics for display too.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thinking about the process, I think a timer is the best way to go for now, I
just have to alter the way I was going to structure my program. With threads,
I have to worry about routines being threadsafe, and working with mutexes and
making sure I have a big enough heap... that's a lot of issues to deal with
that a timer does not have.
That sounds manageable. It wouldn't be too hard for me to time each loop and
keep some sort of statistic of average cycle time so I could adjust the
timer... maybe even have some sort of dynamic process to self-adjust or to run
more or less code depending on how fast it is running. As you say, I just need
to monitor the percentage of time my routine is spending, try to keep below a
certain percent so the rest of the system can run well.
I am not really asking a question now, but since I know other people read
these I will go ahead and present a small outline of what I came up with to
make it work.
The program is a data feeding program to automate tasks in an AS/400 system.
(The primary use will be to feed lists of data, but it will contain a
scripting protocol as well which could lead to other types of tasks.) It will
replace a process I have been using Visual Basic in Excel to do, thereby
freeing my Excel application to be able to do other things while the program
processes the data and also making it easier for me to simplify tasks I do so
I can delegate to others when I need to.
The data will come from files placed into a queue. There will be multiple ways
to add files to the queue, and options such as file priority and what time the
file should process... what's important at this level is that either we are
processing a file or we are not. I will have a separate routine to manage the
queue, under a combination of window control events and a slice of the timer
routine (or its own timer) to do quick monitoring every minute or so.
Anyway, with the main loop on the timer, I think of it as if I am building an
underwater project and I don't have oxygen... as soon as I am in the water I
have a very short amount of time to do one task and come back up for air.
Since I want to play nice with the system, the first thing I will do is see if
I am processing a file or not... if I am not, I will check the status of the
queue to see if it is time to start processing another file. If not, I leave.
Let the other running programs have the advantage.
Then, I am processing so I am in the main loop. At this point, if there will
be multiple steps, I could break them up into step 1, 2, 3, etc. and use a
switch statement and a counter so on each time into the loop it will go
directly to the part of the program it needs to be in.
Since I am dealing with an external system, sometimes it will be busy and I
can't send out data. If I were programming straight, using a thread or a
console program, I would just have the program wait. But since I am on a timer
and I don't want to make all of my applications stop and wait for the AS/400,
if the AS/400 can't take input at this time I will continue to process the
file and put the future keystrokes into a buffer. (So I will have three
tasks... 1. if the AS/400 is available, send a line from the buffer. 2.
process the file a line at a time, and 3. do what the line wants to do. Then
exit the routine.)
If I come to where I need to read the AS/400 (either the status or something
on the screen), or make a decision (the files can be straight data or a
scripting language I am developing which will allow for input and decision-
making), it will stop queuing the buffer and stop processing the file and keep
feeding the buffer into the system until it is empty, then resume with the
processing, meaning once the buffer is empty, it is caught up, then it can
take a snapshot of the as/400's state or read the screen or make the decision.
If I break the program into tasks, say task 1 is handle the buffer, task 2 is
parse a line from the file, task 3 is execute the line, then I can use a
select switch to control the steps. I can take a timer reading when I enter
the routine, then check at the end of each task how much time I have left
until I need to bail from the routine, and decide if I should run the next
step or not. If I do bail, when it gets back it can branch to that step and
continue.
In that way, I can have the program actively processing and sending data and
yielding to the system if the system is being slow... but also still have
access to my menus, watch screens, etc. (Another reason I am writing this code
is that it will track a number of things as it goes along and be able to show
status logs and track errors and have options such as taking snapshots of the
system after each line is transmitted or at specified points so when there is
an error it can show the last five screens for debugging purposes, etc.)
It should be a nice application to have... unfortunately company policy states
that if I make it on their time with their equipment it is theirs, so I will
be able to share it within the company but not beyond that. But I know it will
get use.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am not sure why you need to worry about a 'big enough heap' when using
threads; that is the responsibility of the operating system. Thread safety is
only an issue when threads share data or resources, or non-reentrant
functions. The 'contact points' are usually easy to spot, and IPC rather than
shared memory is a safer method of thread communication.
That said, I agree a timer is the obvious way to go. I think you are making it
far more complex than it is however, checking for a file system change as you
suggested is trivial, you should probably just set the time to match the
response-time you require from the system and be done with it. If it does not
achieve that then you are screwed in any case. Remember on-time is good
enough, ahead-of-time is no advantage.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I actually had this somewhat a long reply but I cut it down a bit, it's not
really important you know my programming experience or why I want to use Dev
C++ or why I will probably end up using VC++ or what else I still need to
research... none of that is relevant in a discussion about timer based
multitasking. So if I need to say those things later I will but right now I
will just delete those sections and make this an easier read.
Checking for a file on the queue is the easy part, I won't go over that more
because it's not my main concern. That will be in and out, no problem.
My concern is that once I am actually processing the file, if I am processing
a large file (say 10,000 records), and parsing a script where it might take
five or six commands before it has the data to send (of course that is on the
script programmer as well), and there's going to be pockets of time between
calls, I want to take advantage of the as/400's wait state so when it is ready
I am ready. That is a variable amount of time, so I think a buffer will be ok.
Ultimately I am trying to shave down the amount of time the AS/400 has to run,
so I think pre-processing might help if the AS/400 is waiting and I have
processing to do before I can send data anyway.
But the issue I think is being pointed out is trying to do three things in one
timer cycle and using variable timers (either changing how often I call or how
much I do in each loop). As I was thinking about this reply I came to the
realization that you are right.
The way I see it, there are two choices here:
Jump into the routine more often and do less each time, or
Jump into the routine less often and do more.
I was thinking option 2 but option 1 is better for Windows and still gets the
same thing done, just maybe a little differently.
Either way, I will want to break my routine into steps and use a counter and a
switch statement to control what part of the program I am in on each entry to
the routine. I think that is a fast and easy way to do it. I can even use
constants like Send Buffer = 1, Parse = 2, Action = 3 to make the code more
readable and understandable. (Of course comments don't hurt either. And having
constants or not, either way, if I add a step between, I have to change the
numbers.)
It's possible I may need to break down the parsing step into sub-steps, if
it's a complicated line and it will obviously take a while to parse, that will
have to be a multiple number of cycles.
For example, if I have a command such as !1500, which will just send out the
number "1500" to be entered in, that will be a very simple parse, just take
the text and put it in the buffer.
However, if I have a command such as set a, (b*(c+5+(d/e))-f)+g, which will
evaluate the equation and put into variable A, that is going to take a lot of
time to process (if we are talking milliseconds), because it has to pull the
values of each variable, and evaluate the equation a level at a time. But if
each level is a cycle, that should be ok, thinking small... and it will just
be a given that having long formulas will slow down the process but at least
it won't negatively affect the other programs. And actually, the way I already
have the expression parser written in VBA (which I am converting now), it
already uses a loop so it won't be that hard to say a loop is a timer cycle.
Thinking that what I have been using is VBA, and what the team I would share
this with has been using is VB Script that has been using COM technology to
read and parse an Excel file, I guess even doing one step each loop (or one
step over three or four loops) and taking the chance that there could be
unused pockets of time, would still be miles faster than we have been having.
Really, when I think about it, if I use threading, the Windows scheduler is
going to break it down into small chunks anyway and run each part a bit at a
time on its own, and it probably won't be truly continuously running, it will
have gaps between as well. By using a timer, I am basically just replacing the
scheduler and making my own.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This may be a simple question..
I want to make a program that runs in Windows using dialog boxes and such, but
unlike applications like calculator that sit and wait for you to do something,
I want something more like media player that plays but still lets you use the
controls.
The getmessage function doesn't move on until it gets a message, so I can't
use that standard pump if I want to make a program that is actively doing
something in the background.
Do I need to make a multi-thread program where one thread handles the window
elements and one thread runs the program?
What my program will do is monitor a certain directory and when there are
files added to the directory, it will process them and send them key by key to
an external system. But while it is doing that I want to be able to have watch
windows, menus, etc.
What are your thoughts?
-Dan
I can think of three solutions; two of them general, and one specific to your
particular problem (and probably the best solution in this case).
The general solutions are:
1) Create a worker thread to perform the activity concurrently to the message
handling procedure.
2) Use a timer to periodically sent WM_TIMER messages to your message handling
procedure and do a 'bit of work' on each event. In this case simply check the
folder you are monitoring.
Method 1 is a bit heavyweight for this particular task, where method 2 would
be more appropriate. However there is another method which is probably better
still. The operating system can watch for file system events for you and send
messages to your message handler when they occur. This is how tools such as
Google Desktop work - only indexing files when they change. In .NET this is
easily achieved using the . I am sure I have seen this done in plain Win32,
but cannot immediately find the appropriate API.
Clifford
: http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher%28VS.80
%29.aspx
Thank you, that's pretty much what I was thinking was either a concurrent
thread or a timer... I was just hoping maybe there is some sort of an
alternate command to getmessage that instead of waiting would fall through and
let me do other things. However, if theoretically there was something like
that, I would still have to break the program down into little pieces and have
it do a small portion and come back to check the message queue again,
otherwise the window controls would lag considerably. Therefore, in theory a
timer is pretty much the same thing, just perhaps not quite as tight because
depending on how long I go between calls, there could be unused time. I'll
play with it, until I have a program complicated enough to need a worker
thread and then I will see how that works.
Interesting to think about just how many programs in Windows really do just
sit and wait... it was hard for me to think of an example of a program that
doesn't.
As far as checking for the file, I will do some research and see if I can find
something I can use in Dev, or I can just have part of the timer loop be
looking... I will still need a timer either way because once the file is found
and it begins the process of processing and exporting, it could be a lengthy
process so I would still need the system to be able to do the window calls as
well. Eventually, I want to be able to do COM support in and out and plug-ins
too so I'll take it all into consideration.
-Dan
Having GetMesage() fall through detrimentally would affect the performance of
other programs running on your machine by hogging a large number of CPU
cycles. In old 16 bit versions of Windows that used cooperative multi-tasking,
it would haveground everything else to a halt by taking all cycles outside
of interrupt handlers. Even with pre-emptive multi-tasking, the Windows
scheduler expects applications to behave responsibly, and continuously using
all the available time-slice will affect other processes that might otherwise
run.
However, should wou wish to do that it is easily done. You can call , and then
only call GetMessage() to clear the queue is there is a message available;
this effecting a non-blocking message handler.
It is a rather inelegant solution however. Threads are not difficult to use
(although again much simpler in .NET - the Win32 API suffers from the weight
of its legacy, and the fact that it is not object oriented).
Clifford
: http://msdn.microsoft.com/en-
us/library/ms644943%28VS.85%29.aspx
Thanks... I am concerned about not hogging all the CPU's resources, I do want
my programs to "play nice" so I'll keep that in mind, if there comes
a critical part that has to be done with tight timing, I suppose I could try
the peekmessage command, but then again if it is that critical of an operation
I probably don't need to worry about menus and windows, etc. because the
operation itself would be more important.
I was hoping even doing a timer wouldn't tie up my computer too much, if I did
it for every half a second or something. I haven't tried it yet, I am still
planning. I will probably use multi-threading when all the pieces come
together... start with a timer and then as I add pieces I will change the
timer to a thread and have flags, like a state machine, to coordinate all the
pieces. Then when I add COM support (I want to be able to query the status of
my program from VBA, because the majority of the files to process will come
from Excel), that will probably be its own thread as well.
I am just used to programming DOS-style, where I get to control everything...
but I have to let go a little and let Windows help me.
Now I see all my options on the table, I can play around a bit.
-Dan
Even very rapid timer event messages (say 50 to 100 per second) would not in
themselves trouble a modern CPU, it is rather how much work you do in each
event that would be critical. For example is you had a timer event every 100ms
and the processing took 90ms, that would be 90% of the CPU dedicated to your
task. If you are watching for file or folder changes the polling rate would be
determined entirely on how soon after such an event you need your program to
react.
Either way, the Windows Task Manager will tell you teh total CPU load and teh
specific load for individual processes. Use that to check the behaviour of
your program. On the processes list you can add all sorts of additional
metrics for display too.
Thinking about the process, I think a timer is the best way to go for now, I
just have to alter the way I was going to structure my program. With threads,
I have to worry about routines being threadsafe, and working with mutexes and
making sure I have a big enough heap... that's a lot of issues to deal with
that a timer does not have.
That sounds manageable. It wouldn't be too hard for me to time each loop and
keep some sort of statistic of average cycle time so I could adjust the
timer... maybe even have some sort of dynamic process to self-adjust or to run
more or less code depending on how fast it is running. As you say, I just need
to monitor the percentage of time my routine is spending, try to keep below a
certain percent so the rest of the system can run well.
I am not really asking a question now, but since I know other people read
these I will go ahead and present a small outline of what I came up with to
make it work.
The program is a data feeding program to automate tasks in an AS/400 system.
(The primary use will be to feed lists of data, but it will contain a
scripting protocol as well which could lead to other types of tasks.) It will
replace a process I have been using Visual Basic in Excel to do, thereby
freeing my Excel application to be able to do other things while the program
processes the data and also making it easier for me to simplify tasks I do so
I can delegate to others when I need to.
The data will come from files placed into a queue. There will be multiple ways
to add files to the queue, and options such as file priority and what time the
file should process... what's important at this level is that either we are
processing a file or we are not. I will have a separate routine to manage the
queue, under a combination of window control events and a slice of the timer
routine (or its own timer) to do quick monitoring every minute or so.
Anyway, with the main loop on the timer, I think of it as if I am building an
underwater project and I don't have oxygen... as soon as I am in the water I
have a very short amount of time to do one task and come back up for air.
Since I want to play nice with the system, the first thing I will do is see if
I am processing a file or not... if I am not, I will check the status of the
queue to see if it is time to start processing another file. If not, I leave.
Let the other running programs have the advantage.
Then, I am processing so I am in the main loop. At this point, if there will
be multiple steps, I could break them up into step 1, 2, 3, etc. and use a
switch statement and a counter so on each time into the loop it will go
directly to the part of the program it needs to be in.
Since I am dealing with an external system, sometimes it will be busy and I
can't send out data. If I were programming straight, using a thread or a
console program, I would just have the program wait. But since I am on a timer
and I don't want to make all of my applications stop and wait for the AS/400,
if the AS/400 can't take input at this time I will continue to process the
file and put the future keystrokes into a buffer. (So I will have three
tasks... 1. if the AS/400 is available, send a line from the buffer. 2.
process the file a line at a time, and 3. do what the line wants to do. Then
exit the routine.)
If I come to where I need to read the AS/400 (either the status or something
on the screen), or make a decision (the files can be straight data or a
scripting language I am developing which will allow for input and decision-
making), it will stop queuing the buffer and stop processing the file and keep
feeding the buffer into the system until it is empty, then resume with the
processing, meaning once the buffer is empty, it is caught up, then it can
take a snapshot of the as/400's state or read the screen or make the decision.
If I break the program into tasks, say task 1 is handle the buffer, task 2 is
parse a line from the file, task 3 is execute the line, then I can use a
select switch to control the steps. I can take a timer reading when I enter
the routine, then check at the end of each task how much time I have left
until I need to bail from the routine, and decide if I should run the next
step or not. If I do bail, when it gets back it can branch to that step and
continue.
In that way, I can have the program actively processing and sending data and
yielding to the system if the system is being slow... but also still have
access to my menus, watch screens, etc. (Another reason I am writing this code
is that it will track a number of things as it goes along and be able to show
status logs and track errors and have options such as taking snapshots of the
system after each line is transmitted or at specified points so when there is
an error it can show the last five screens for debugging purposes, etc.)
It should be a nice application to have... unfortunately company policy states
that if I make it on their time with their equipment it is theirs, so I will
be able to share it within the company but not beyond that. But I know it will
get use.
Anyway, my point about programming timers as a method of having active modules
on top of windowing framework is:
If you don't have anything to do, get out as soon as possible,
Make the process as simple as possible, and
if you need to do multiple things, you can break the process into pieces and do one piece on each loop, by using a switch statement and a counter.
Think of it as being underwater and coming up for air every so often.
I am not sure why you need to worry about a 'big enough heap' when using
threads; that is the responsibility of the operating system. Thread safety is
only an issue when threads share data or resources, or non-reentrant
functions. The 'contact points' are usually easy to spot, and IPC rather than
shared memory is a safer method of thread communication.
That said, I agree a timer is the obvious way to go. I think you are making it
far more complex than it is however, checking for a file system change as you
suggested is trivial, you should probably just set the time to match the
response-time you require from the system and be done with it. If it does not
achieve that then you are screwed in any case. Remember on-time is good
enough, ahead-of-time is no advantage.
I actually had this somewhat a long reply but I cut it down a bit, it's not
really important you know my programming experience or why I want to use Dev
C++ or why I will probably end up using VC++ or what else I still need to
research... none of that is relevant in a discussion about timer based
multitasking. So if I need to say those things later I will but right now I
will just delete those sections and make this an easier read.
Checking for a file on the queue is the easy part, I won't go over that more
because it's not my main concern. That will be in and out, no problem.
My concern is that once I am actually processing the file, if I am processing
a large file (say 10,000 records), and parsing a script where it might take
five or six commands before it has the data to send (of course that is on the
script programmer as well), and there's going to be pockets of time between
calls, I want to take advantage of the as/400's wait state so when it is ready
I am ready. That is a variable amount of time, so I think a buffer will be ok.
Ultimately I am trying to shave down the amount of time the AS/400 has to run,
so I think pre-processing might help if the AS/400 is waiting and I have
processing to do before I can send data anyway.
But the issue I think is being pointed out is trying to do three things in one
timer cycle and using variable timers (either changing how often I call or how
much I do in each loop). As I was thinking about this reply I came to the
realization that you are right.
The way I see it, there are two choices here:
Jump into the routine more often and do less each time, or
Jump into the routine less often and do more.
I was thinking option 2 but option 1 is better for Windows and still gets the
same thing done, just maybe a little differently.
Either way, I will want to break my routine into steps and use a counter and a
switch statement to control what part of the program I am in on each entry to
the routine. I think that is a fast and easy way to do it. I can even use
constants like Send Buffer = 1, Parse = 2, Action = 3 to make the code more
readable and understandable. (Of course comments don't hurt either. And having
constants or not, either way, if I add a step between, I have to change the
numbers.)
It's possible I may need to break down the parsing step into sub-steps, if
it's a complicated line and it will obviously take a while to parse, that will
have to be a multiple number of cycles.
For example, if I have a command such as !1500, which will just send out the
number "1500" to be entered in, that will be a very simple parse, just take
the text and put it in the buffer.
However, if I have a command such as set a, (b*(c+5+(d/e))-f)+g, which will
evaluate the equation and put into variable A, that is going to take a lot of
time to process (if we are talking milliseconds), because it has to pull the
values of each variable, and evaluate the equation a level at a time. But if
each level is a cycle, that should be ok, thinking small... and it will just
be a given that having long formulas will slow down the process but at least
it won't negatively affect the other programs. And actually, the way I already
have the expression parser written in VBA (which I am converting now), it
already uses a loop so it won't be that hard to say a loop is a timer cycle.
Thinking that what I have been using is VBA, and what the team I would share
this with has been using is VB Script that has been using COM technology to
read and parse an Excel file, I guess even doing one step each loop (or one
step over three or four loops) and taking the chance that there could be
unused pockets of time, would still be miles faster than we have been having.
Really, when I think about it, if I use threading, the Windows scheduler is
going to break it down into small chunks anyway and run each part a bit at a
time on its own, and it probably won't be truly continuously running, it will
have gaps between as well. By using a timer, I am basically just replacing the
scheduler and making my own.