I have problem with callbacks from other application thread. Dll is some kind of wrapper between Addinational application and Application program and its working within Application program memory(with same PID). Addinational application(other thread and PID) is application which in main loop looking for "something" and when found it, it calls Callback function from Dll and then Dll calls Callback function from Application program. Maybe its little confusing look at image above.
And theres crash(when dll calls callback function from application program) with message:
Unhandled exception at 0x70786a46 in MainProgram.exe: 0xC0000005: Access violation reading location 0x00000164.
Call stack mshtml.dll
Propably application program using IE controls to update UI. How could I update UI when Addinational application callsback?
SendMessage is a general solution for posting results to a GUI thread. It does all thread synchronization for you and doesn’t return until the message has been processed by the receiver thread's window.
PostThreadMessage is less reliable since the message may/will be lost when the receiver is in a modal loop for e.g. MessageBox, unless you have added a hook that intercepts the thread message – so just use SendMessage.
More advanced techniques involve doing the thread synchronization yourself, e.g. with a buffer, but anyway that will probably also involve SendMessage for a GUI thread, so, I suggest you just start with that, and if that’s good enough, then don’t do more.
EDIT: dang, I see now that although the first sentence talks about threads, it's really about sending data from one process to another process. Well, for that there is WM_COPYDATA. Please consider that a (user level) pointer from one process, is not valid in the other process.
So you want to call a function that belongs to another process. I think you need to read about RPC:s http://msdn.microsoft.com/en-us/library/windows/desktop/aa378651%28v=vs.85%29.aspx
Related
Back to stackoverflow with another question after hours of trying on my own haha.
Thank you all for reading this and helping in advance.
Please note the console program has following functionalities:
connect to a frame grabber
apply some configs
store the incoming data (640 * 480 16-bit grayscale imgs) in a stream of buffers inside a while loop
Exits the while loop upon a key press.
disconnect from device
And I'm only adding the displaying the images functionality on the MFC GUI app. In short,
i) Converting a console app to an MFC app (dialog based)
ii) decided to use thread for displaying images, but DK how to properly exit from thread when there are certain tasks to be done (such as call disconnectFromDevice(); freeBuffers();, etc) before exiting the thread.
iii) have tried making the while loop condition false but didn't work
( I actually want this to be a callback function that's called repeatedly but IDK how to implement it inside a thread)
iv) forcing AfxEndThread didn't work and it's not even the way it should be done (I think).
So my question is,
1. Are you supposed to use a while loop to excuete a certain job that should repeatedly be done? If not, do you have to implement a callback inside a thread? Or use Windows message loop? Why and how? Please provide a hello-world-like sample code example
(for example, you are printing "hello world" repeatedly inside a thread with a condtion in an MFC GUI app. How do you update or check the condition to end the thread if you can't just AfxEndThread() inside the threadproc)
2. If it's ok with a while, how do you exit from the while loop, in other words how do you properly update the exit condition outside the thread the while loop's in?
Please refer to the source code in the provided link
ctrl+F OnBnClickedConnectButton, AcquireImages and OnBnClickedDisconnectButton
https://github.com/MetaCortex728/img_processing/blob/main/IR140Dlg.cpp
Worker threads do not have message-queues, the (typically one and only) UI one does. The message-queue for a thread is created by the first call of the GetMessage() function. Why use messages to control processing in a worker thread? You would have to establish a special protocol for this, defining custom messages and posting them to the queue.
Worker threads can be implemented as a loop. The loop can be terminated based on various conditions, like failures to retrieve any data or request from the user. You can simply exit the thread proc to terminate the thread's execution. If the thread doesn't respond it may have stuck (unless it performs a really lengthy operation) and the UI thread must provide some mechanism to kill it. That is first request termination and if it doesn't respond within some set time then kill it.
The condition mechanism to terminate should best be some synchronization object (I would recommend a manual-reset event), interlocked variable or a simple boolean which you should access and set using a critical section.
Some considerations:
You pass a parameter block to the thread. Make sure that it remains alive throughout the thread's lifetime. For example, it should NOT be a local variable in a function that exits before the thread's termination.
The loop must be "efficient", ie do not loop infinitely if data are not available. Consider using blocking functions with timeouts, if available.
Resource management (eg connecting/disconnecting, allocating/releasing etc) should best be performed by the same thread.
An alternative implementation can be APCs. Then the thread's proc function is a while(!bTerminate) { SleepEx(INFINITE, TRUE); } loop, and other threads issue requests using a the QueueUserAPC() function.
The AfxEndThread(0) call in OnBnClickedDisconnectButton() is wrong, it terminates the current thread, which in this case is the main (UI) thread. Check the documentation.
A sidenote, my suggestion about the project type is not a dialog-based application but instead a normal MFC application without a document class (uncheck the Document/View architecture support option), as it offers features like menus, toolbars and the like, and most importantly the ON_UPDATE_COMMAND_UI handlers.
I have an operation which ends in about 20 seconds. To avoid freezing, I want to create a thread and update a label text in it every second. I searched a lot, since everyone has different opinion, I couldn't decide which method to use.
I tried SendMessage and it works but some people believe that using SendMessage is not safe and I should use PostMessage instead. But PostMessage fails with ERROR_MESSAGE_SYNC_ONLY (1159).
char text[20] = "test text";
SendMessage(label_hwnd, WM_SETTEXT, NULL, text);
I searched about this and I think it's because of using pointers in PostMessage which is not allowed. That's why it fails.
So, what should I do? I'm confused. What do you suggest? Is this method is good for change UI elements in other thread?
Thanks
The documentation for ERROR_MESSAGE_SYNC_ONLY says:
The message can be used only with synchronous operations.
This means that you can use synchronous message delivery, i.e. SendMessage and similar, but you cannot use asynchronous message delivery, i.e. PostMessage.
The reason is that WM_SETTEXT is a message whose parameters include a reference. The parameters cannot be copied by value. If you could deliver WM_SETTEXT asynchronously then how would the system guarantee that the pointer that the recipient window received was still valid?
So the system simply rejects your attempt to send this message, and indeed any other message that has parameters that are references.
It is reasonable for you to use SendMessage here. That will certainly work.
However, you are forcing your worker thread to block on the UI. It may take the UI some time to update the caption's text. The alternative is to post a custom message to the UI thread that instructs the UI thread to update the UI. Then your worker thread thread can continue its tasks and let the UI thread update in parallel, without blocking the worker thread.
In order for that to work you need a way for the UI thread to get the progress information from the worker thread. If the progress is as simple as a percentage then all you need to do is have the worker thread write to, and the UI thread read from, a shared variable.
Well, the error says it all. The message cannot be sent asynchronously. The thing about PostMessage is that it posts the message to the listening thread's queue and returns immediately, without waiting for the result of message processing. SendMessage on the other hand, waits until the window procedure finishes processing the message and only then it returns.
The risk of using PostMessage in your case is that before window procedure processes the message you may have deallocated the string buffer. So it is safer to use SendMessage in this instance and that's what MS developers probably thought about when they decided not to allow asynchronous posting of this particular message.
EDIT: Just to be clear, of course this doesn't eliminate the risk of passing a naked pointer totally.
From MSDN
If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail.
The asynch PostMessage() alternative requires that the lifetime of the data passed in the parameters is extended beyond the message originator function. The 'classic' way of doing that is to heap-allocate the data, PostMessage a pointer to it, handle the data in the message-handler in the usual way and then delete it, (or handle it in some other way such that it does not leak). In other words, 'fire and forget' - you must not touch the data in the originating thread after the PostMessage has been issued.
The upside is that PostMessage() allows the originating thread to run on 'immediately' and so do further work, (maybe posting more messages). SendMessage() and such synchronous comms can get held up if the GUI is busy, imacting overall throughput.
The downside is that a thread may generate mesages faster than the GUI can process them. This usually manifests to the by laggy GUI responses, especially when performing GUI-intenisve work like moving/resizing windows and updating TreeViews. Eventually, the PostMessage call will fail when 10,000+ messages are queued up. If this is found to be a problem, additional flow-control may have to be added, so further complicating the comms, ( I usually do that by using a fixed-size object pool to block/throttle the originating thread if all available objects are stuck 'in transit' in posted, but unhandled, messages.
I think you can use SendMessage safely here. Then you don't need to worry about memory persistence for your string and other issues.
SendMessage is not safe when you send messages from another message handler or send message to blocked GUI thread, but if in your case you know it is safe - just use it
This is not a problem with the PostMessagebut a problem with the message you are sending - WM_SETTEXT. First a common misconception is that if you SendMessage() to a control from a thread, it is different from calling GUI API, it is in fact NOT. When you call a GUI API (from anywhere) for example to set text, windows implement this in the form of SendMessage() call. So when you are sending the same message, it is essentially same as calling the API. Although directly GUI access like this works in many ways it is not recommended. For this reason, I would beg to disagree with the accepted answer by #David.
The correct way is (code on the fly)
char* text = new char[20]
strcpy_s(text, "test text");
PostMessage(label_hwnd, IDM_MY_MSG_UPDATE_TEXT, NULL, text);
you will updated the text in your own message IDM_MY_MSG_UPDATE_TEXT handler function and delete the memory.
[I might be wrong about these]
TIdTCPServer Server is multithreaded in Borland C++ builder. It handles all client's on seperate threads. This is written in help of Borland c++.
Now is my problem & question.
For example, ShowMessage(String ..) method should be called on main (gui) thread. But as I say above, TCPServer is multithreaded and handles OnExecute event on different threads. When I use ShowMessage method in OnExecute event (which is handled on a different thread than main thread), I get weird results. Sometimes ShowMessage() works as expected, sometimes it is shown without any text on it with different box sizes(infinite lengt, very long, normal, etc). The other user interface changes causes no problem(update TEdit, TMemo. Only ShowMessage() has problem for now)
I think this problem is the result of calling ShowMessage() method not on the main (gui) thread but on TCPServer's thread which is created for client connections internally by TIdTCPServer.
So how can I fix it?
ShowMessage() displays a VCL TForm, and as such is not thread-safe. You have to use TThread::Synchronize(), TThread::Queue(), TIdSync, TIdNotify, or any other inter-thread communication mechanism of your choosing to make ShowMessage() run on the main thread.
To display a popup message in a worker thread, use the Win32 API MessageBox() function instead. It is thread-safe, and can be called in any thread without synchronizing with the main thread.
All changes to the user interface should be done in the main thread. You can use the TThread::Queue function for executing a function in the main thread. It posts a message to the main message queue, and the TThreadMethod passed as a parameter gets executed when the main thread handles messages.
If you need to pass data to the main thread, e.g. the message to be shown, you'll have to do that separately, as function parameters cannot be passed via the Queue function.
Yes your issue has most probably nothing to do with TCP. Any VCL access must be done within the main thread. (do not forget that message dialogs are often called from VCL wrapers and not directly through winapi)
Yeas I know it sometimes works 'well' even when not, but then this issues appears:
always an exception an App close/exit
occasional App hang/exception (fatal or non fatal for App)
occasional corrupted VCL visual stuff (missing items in lists, missed events, etc)
occasional unpredictable behaviour (sometimes overwrite even App non VCL data)
Many occasional issues are repeatable dependent on:
UI complexity
source code complexity (bigger code more often issues)
number of windows/forms
Also beware of memory leaks. VCL is extremly unstable if memory manager is corrupted by invalid deletes etc... (do not know how about it in newer versions but in bds2006 is this very big issue)
PS. if you need just dialogs then use WINAPI interface it should work even in threads if your text data is not VCL related (for example AnsiString variable access is fine but DBGrid access is not)
When using the MiniDumpWriteDump function to create a core dump of a process on Windows, it is recommended (e.g. here, and here) that the MiniDumpWriteDump is run from another "watchdog" process because it may well not work when called from within the same process.
At the moment, our application is calling it in-process on an unhandled exception (we do it from a watchdog thread). Since we sometimes have problems with it not working, we'd like to move it to a separate process.
Now, signalling the other process to start writing the dump is trivial (just use an event, semaphore, you name it) but how do I pass the LPEXCEPTION_POINTERS info I get for the callback function I register with SetUnhandledExceptionFilter to the other process so that it can be passed to MiniDumpWriteDumps ExceptionParam argument??
You also need the MINIDUMP_EXCEPTION_INFORMATION.ThreadId value. The simplest way, and the way I made it work, is to use a memory-mapped file to transfer both the ThreadId and the ExceptionPointers. And a named event to wake up the watchdog. It doesn't matter that the pointer is not valid in the context of the watchdog process.
Use CreateFileMapping + MapViewOfFile in the watched process as part of its initialization, OpenFileMapping + MapViewOfFile in the watchdog. Your SetUnhandledExceptionFilter should then only call GetCurrentThreadId() and copy the tid and the pExcept to the memory mapped file view, call SetEvent() to wake up the watchdog and block forever until the watchdog terminates it.
While Hans answer is correct, I found that an easier way is to use WM_COPYDATA to transfer information from main process to minidump process. Register a class and a HWND_MESSAGE type window with some custom names in minidump process, then wait for WM_COPYDATA message in WndProc. Use FindWindow with same class name and window name in main process to obtain HWND to your minidump window. Use SendMessage with this handle to send WM_COPYDATA message with whenever struct you want to use. This will block your application until minidump process will receive and process it. Note that one of WM_COPYDATA parameters is a handle to window that sent it, but you will still need to use OpenProcess to get a proper process handle to use in MiniDumpWriteDump, so a "minimal" message to send is probably
process ID (to obtain process handle with OpenProcess)
thread ID (to initialize MINIDUMP_EXCEPTION_INFORMATION)
LPEXCEPTION_POINTERS (to initialize MINIDUMP_EXCEPTION_INFORMATION)
This way you will get all the necessary data in minidump's WndProc to call MiniDumpWriteDump. Make sure to set ClientPointers field in MINIDUMP_EXCEPTION_INFORMATION to TRUE since we're debugging external process. Note that when running under debugger in MSVC the call to MiniDumpWriteDump might produce flurry of exceptions like trying to read invalid memory address - simply ignore this, it's normal (and you don't need to intercept any of those)
Once your minidump process finished writing the dump, it will return from WndProc and main process will return from SendMessage. Then you can either terminate your main app or do any other stuff in exception handler (e.g. we show a nice message box to user and close the app gracefully).
I'm using UI threads and I built one thread with message map and it works fine, the problem is when I'm tring to create another thread from the first one.
When I'm getting to this line:
this->PostThreadMessage(WM_MYTHREADMESSAGE,0,0);
I'm getting the next message:
"No symbols are loaded for any call stack frame. The source code cannot be displayed"
I dont know if its could be the reason for the problem but I have built two message maps, one for each thread, I don't know if its ok to do so.
The question is difficult to understand. I'm assuming that you're stepping through your program in the debugger, and you get to that PostThreadMessage line.
If you choose Step Into, the debugger will try to step into the PostThreadMessage call (or the framework wrapper, depending on the type of this). Since PostThreadMessage is a system call, it's likely you don't have symbols for that code. The debugger will just show you disassembly. You can try to use the Microsoft symbol server, but I don't see much point in trying to trace into PostThreadMessage. If the parameters are right, it's going to post the message to the specified thread's queue. Not much to see there.
Posting message to other threads is tricky business. Most Windows programs, even multithreaded ones, typically keep all the UI work to a single thread. It can be done, but there are a lot of caveats and it's usually not worth the pain.
So there are couple of things:
if you want to notify the UI thread from the worker thread, then you should not use PostThreadMessage, here is why.
When this->PostThreadMessage(...) called in a member function of thread A, the message will be sent to thread A, because this points to CWinThread of A. You have to get a pointer to the other thread to post a message to it.
Finally if you want to notify your UI thread, use PostMessage to send a message to the window created by that thread. Add a corresponding handler to the window message map.
Hope this helps