Pregunta

[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?

¿Fue útil?

Solución 2

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.

Otros consejos

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.

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:

  1. always an exception an App close/exit
  2. occasional App hang/exception (fatal or non fatal for App)
  3. occasional corrupted VCL visual stuff (missing items in lists, missed events, etc)
  4. 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)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top