|
Thanks!
The short version is that your suggestions about reorganising the Threading certainly simplified things and may well have been 90% responsible for solving the problem (I'll come back to the 10%, below)
The longer version:
1. Agreed!
2. Done, with very minor modifications. The While loop blocks "automatically" on the UDPClient.Receive call, which doesn't return until the next Status Report packet arrives, 10 seconds later.
3. Done (and in one other place in the Class)
4. It was actually only the first packet sent after the (initial and only) UDPClient.Connect call that seemed to have problems - only that packet was sent twice by my original code (the first For loop has an early exit). Your code sends every packet twice, which was not my intention!
5. Threads (up until recently) weren't my thing. Data structures are! There are (IMHO) good reasons for the way I am doing this.
6. I have resorted to this sort of approach once or twice (more when I was writing real-time data acquisition and control stuff), but haven't found it useful in general programming often enough to put the "hooks" for it in my code on a routine basis.
7. It appears from further experimentation with the modified code that you do need delays between at least some calls to UDPClient Methods, and that I wasn't leaving quite enough time between them in some cases. Sleeping for 200 msec seems to work reliably for my situation - 100 msec is not always enough. I think that it is possible that the Application.DoEvents calls were "working" simply because they were wasting more time, and the poor threading code may also have been only a contributing factor to the problems.
|
|
|
|
|
I'm glad you got on top of it, well mostly anyway.
5.
I've done lots of real-time stuff, even with queues. One very neat trick is this:
- create two queues, lets call them FULL and EMPTY; FULL will represent the functional queue, EMPTY will be the store for messages currently not in use;
- create N messages, put all of them in the EMPTY queue;
- have the producer get a message from the EMPTY queue, fill it, and put it in the FULL queue;
- have the consumer get a message from the FULL queue, execute it, and put it in the EMPTY queue.
The net result is you don't need object creation/destruction once things have been initialized; and you get an automatic dataflow-limited behavior, as either queue will never hold more than N items.
It works just great, provided all messages have the same type (or size).
6.
Same here. In embedded systems, you typically want to observe without halting everything, hence logging fits the bill.
What remains to be done IMO is figuring out why you need your delays. Is it related to the reaction time of your thermostat? (i.e. is it deaf while processing an earlier command or transmitting a result?) Timestamped logging should help out here as well.
|
|
|
|
|
5. In this case, all the messages are not the same size (the message header length is constant, but a message can contain 0, 1, 2, or an arbitrary (2 < n <= 26) number of additional bytes of data). Also, for a number of reasons related to the device and application, I want to be able to identify and (if necessary) modify a pending command, if another command of the same "class" is issued before the first one is executed, which may be up to 10 seconds later.
The thermostat is relatively slow (in computer terms), and can only do one thing at a time, but I don't think that this can be causing the need for the delays. If I don't put them in, some of the UPD packets are never sent. It is as if the outgoing UDP port needs time to "clear" before it will send a new message.
|
|
|
|
|
I need help how i can add differen control in datagirdview in a singel column.
Like
ProperName showvaule
testName show value in combox
testName2 show value in text
testName3 show value in combox
|
|
|
|
|
This is going to be a huge pain to do. The DGV was designed to have a single display control and edit control in any one column. What you would have to do is create your own custom DatGridViewColumn classes that determines which edit control to display based on some criteria. You can find an example of creating a custom column here[^]. Note that doing this requires three seperate classes.
|
|
|
|
|
hi members
I want to retrieve the application path of program which is currently running in task manager, please help me.
|
|
|
|
|
System.Diagnostics.Process.GetProcessesByName will give you access to the process.
Call .MainModule.FileName will return the full path to the exe.
|
|
|
|
|
To Get path of running Application listen in TaskManager you can use Given Code
Take a List box and a Button and write given code in click event of button.
foreach (Process p in Process.GetProcesses())
{
string procFile;
try
{
procFile = p.Modules[0].FileName;
}
catch (Win32Exception ex)
{
procFile = ex.Message;
}
listBox1.Items.Add(string.Format("Process {0}: {1}", p.ProcessName, procFile));
}
|
|
|
|
|
Hello coders,
I've been wondering this for some time, but haven't been able to find an answer to: How does DoEvents actually work (technically seen)?
The way I look at it, you have this picture describing your single-threaded application:
[ Your code ]
[ Translation to .NET events ]
[ Message Pump ]
With basically messages coming in from Windows at the Message Pump level, then advancing up until it reaches your code in terms of Events. Your code runs etcetera, and whenever execution 'pauses' (e.g. disappears when debugging), the message pump gets execution again and handles messages. Somewhere parallel is the garbage collector, asynchronously cleaning up your mess in collect 'n reap batches. Am I at least right about this picture (if not, then my question might not make sense)?
The actual question then is: how does DoEvents, called from your code, manage to fall back into the Message Pump? I'd think you need to re-enter the calling function, so basically advance through the stack back to the caller, without losing all the context allowing you to move up to your original point of execution. That means that a simple call to the message pump 'function' would not be the way to, because then it would end up a top of the stack.
One solution to this I was thinking of was to use something like SendMessage(WM_USER_IDLE, ...) to get back into the message pump, but is that even possible/allowed? Does anyone know the answer, because I am REALLY curious
Thanks for reading my rant, and I'll hope you have some answers,
Richard
|
|
|
|
|
There is no such thing as "the message pump", i.e. you can have as many pumps as you like.
Example: when you show a dialog, it has its own message pump, which processes messages related to the dialog and ignores the others.
DoEvents() looks like yet another message pump, which processes everything until there are no more messages, then returns. And it is pretty dangerous to call DoEvents() from within an event handler, as it may cause that very handler to be called again, i.e. it may re-enter which you probably did not intend nor anticipate.
|
|
|
|
|
So it really is another message pump (quite like the original) atop of the call stack? For some reason, I felt it couldn't be that, but don't know exactly why. Probably because this new message pump would have to have the same behaviour as the original. I guess it's possible in an environment like .NET (or VB runtime before that).
Thanks for your answer.
|
|
|
|
|
Luc Pattyn wrote: you can have as many pumps as you like.
Correct.
Luc Pattyn wrote: a dialog, it has its own message pump
In general not correct. However, modal dialogs usually have their own message pump.
Time you enjoy wasting is not wasted time - Bertrand Russel
|
|
|
|
|
that is what I meant, to me a dialog is a modal window and a modal dialog a tautology.
|
|
|
|
|
Windows under the hood is still basicaly a non-preemptive multitasking OS, meaning that on a given processor core, individual threads are allocated execution time slices by the system one at a time. During your thread's slice of time, your application has the core and can execute as long as it sees fit, returning to the system when you are done. In such an OS for an application to "play nice" with others, if you running a long execution, you would intersperce your code with DoEvents (especially if you have a long running loop, you put a DoEvents in the loop) to allow the OS to have a timeslice to perform it's housekeeping routines, send pending messages, etc.. In other words, DoEvents allows your code to return execution to the OS for a timeslice then execution returns to you where you left off. This is especially handy if you are coding a Windows Forms app that updates it's screen elements as your code is running (example a progress bar). If you don't allow the OS a timeslice to send messages to your program to re-draw, your window will seem to freeze untill your long running process is finished and execution is returned to the OS (your app's screen won't redraw).
Kevin Rucker, Application Programmer
QSS Group, Inc.
United States Coast Guard OSC
Kevin.D.Rucker@uscg.mil
"Programming is an art form that fights back." -- Chad Hower
|
|
|
|
|
Spectre_001 wrote: Windows under the hood is still basicaly a non-preemptive multitasking OS
I don't agree. The Windows kernel is event driven, is priority based, is pre-emptive, has fairness implemented, and contains some protection against CPU monopolizing processes. There is no need to call DoEvents(), or anything else, at all to get things to work properly. Here is a simple test: create a process that contains a long computation and have it optionally generate output while computing; now run a number of instances and watch how each of them is proceeding.
Windows is not a real-time OS, which means it is not guaranteeing much on latency; however it does not need the user's cooperation to provide a good interactive user experience. There are ways to make an app behave badly, one of them would be to execute long or blocking stuff on a WinApp's main thread; and there are ways to make an app fail, one of them is calling Application.DoEvents() causing code to get re-entered while it wasn't designed for re-entrance to start with.
BTW: none of the misbehavior mentioned (block GUI thread, call DoEvents) would negatively affect other processes.
|
|
|
|
|
I thought this question was going to be about the access function (does the same kind of thing)
*shudders at recollection of coding in access*
---Guy H ---
|
|
|
|
|
Guy Harwood wrote: *shudders at recollection of coding in access*
Ahh the heady days of my youth spent coding VBA... I can barely remember what it was like to end a line of code without a semicolon and have a hard time doing it when I wander into VBA to trick out a macro in Excel for a co-worker these days. Makes me feel old to think of how long ago that was (mid 90's).
Mike Devenney
|
|
|
|
|
Reflector is your friend:
public static void DoEvents()
{
ThreadContext.FromCurrent().RunMessageLoop(2, null);
}
If you keep poking deeper, you see that it's just running a message loop to handle any messages that might have been sent.
|
|
|
|
|
I beleive DoEvents call moves the pointer on the call stack to where the Windows Messages are, saving the current point and then returning to it after the windows messages are processed.
Of course not this over simplified but I beleive the logic works this way...
|
|
|
|
|
That is not correct. The Windows Message queue is not "on" the stack. No weird call stack operations are performed.
For .Net Application.Run() and Application.DoEvents() are somewhat similar in that they both call a message pump. A message pump could be very simply be:
MessagePump()
{
while ( true )
{
Message msg = GetMessage();
DispatchMessage( msg );
if ( msg.Msg == WM_QUIT ) break;
}
}
The code behind DispatchMessage will eventually call your events, e.g. when a button is clicked.
If you then do a form.ShowDialog() it will re-enter the message pump function (recursively, the previous call just stays on the call stack).
This is why showing a message box in a timer event handler will result in stacking up message boxes until resources are exhausted or a stack overflow occurs.
The call stack will look something like this (looking at it top-down) :
Application.Run
MessagePump
DispatchMessage
... framework stuff ...
Timer1.TimerEvent
SomeForm.ShowDialog
Application.DoEvents
MessagePump
DispatchMessage
... framework stuff ...
Timer1.TimerEvent
SomeForm.ShowDialog <-- if you indeed do this call then this will repeat until...
modified on Wednesday, September 8, 2010 2:36 PM
|
|
|
|
|
That's exactly what I meant, for example, if our heavy processing code is inside DispatchMessage, it might simply do "Goto address 1" as exemplified below and push the current address on the stack so it can be popped after the goto call finishes:
MessagePump()
{
while ( true )
{
Adr 1 Message msg = GetMessage();
Adr 2 DispatchMessage( msg );
Adr 3 if ( msg.Msg == WM_QUIT ) break;
}
}
Again, that's how I think it works.
|
|
|
|
|
This is low level Windows API view, not sure how dotNET sits on top.
1. Each Thread can have its own message pump if needed. If you have windows created on multiple threads, they can run separately. (97% sure)
2. A modal dialog must provide a new message pump, because it is called from the current stack of the "calling" message pump. The "calling" message pump is frozen until the modal dialog's pump exits. This is how you can get a return value from the Modal dialog during the event dispatching of the calling pump. This is also the case with Menus. The event handler for the menu is called from a different pump.
3. Prior to Windows XP(?), the only way to share the cpu with other Windows apps was when calling GetMessage() or PeekMessage(). It really was "play nice or don't play at all." You had to make sure that you "chunked" background work in such a way that you invoked PeekMessage() occasionally.
I am pretty sure that even Windows 95/98?/ME? were 32bit wrappers around the same old Windows 1.0 core. Pre-emption was enforced on DOS virtual machines, but all Windows apps ran in the same VM. This was great because you could actually locate and read memory structures out of other running programs on the system! WinNT families were pre-emptive and full protected memory spaces out of the starting block. There is probably a windows genealogy somewhere that says when certain features were introduced when.
|
|
|
|
|
I'm surprised that no one has pointed to MSDN for this: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx[^]
I know MSDN isn't always helpful, but it tells you what it does as well as when to use it and when not to use it.
Realistically, most circumstances where it is not safe to call DoEvents indicates that you are doing something wrong (such as raising the event in its own handler). Note: the emphasis is on "most" since there are exceptions to almost every rule.
I don't claim to be a know it all, for I know that I am not...
I usually have an answer though.
|
|
|
|
|
MSDN unforunately doesn't say HOW it does it, which was what I wanted to know.
I pretty much always check MSDN; I find it very helpful.
I already have a lot of experience using DoEvents in a correct way in VB6. With .NET I much prefer a worker thread though, for many reasons.
Thanks for all the responses
|
|
|
|
|
Hello All ,
I have used a CalendarExtender in my page with textboxes. When I press enter key in another textbox, calendar's popup is appearing.
I have used defaultbutton attribute in form tag and tried keeping my button id as defalut button but this is also not working.
Please help me out in same..
Thanks In Advance
|
|
|
|
|