How do I create a thread that makes changes to a label in my CLR application? - clr

I apologize if my question is too comprehensive:
I have experience with visual c++ and Qt and I know how to do this in those environments but for the sake of the team, I need to make a CLR application.
I have a CLR Application as follows:
CLR application with a label element. (Unable to post images due to new account).
My requirement:
I want to create a thread that changes the "Status here" label to display a simple string of data.
The reason for this is: I have another c++ based client application which sends data through a named pipe to this application.
My goal is to make a separate thread for this GUI form which does blocking connects and reads from the client and displays the data in a tabular form in this form.
What I want to do is to know how I can modify items in the form after receiving the data from the pipe
What kind of threads should I use, should I use the CLR thread pool or create a thread using System::Threading as follows:
ThreadStart^ pTOperation = gcnew ThreadStart(startPipe);
Thread^ pipeThread = gcnew Thread(pTOperation);
pipeThread->Start();
where my startPipe operation is going to perform the functions of creating a server pipe, connecting with the client, doing reads and modifying the GUI elements.
Does CLR have restrictions for modifying the main form elements from another thread like Qt does. (I had to implement a signal/slot system for that).
my idea: Can I pass an argument to the thread function that is a pointer to the forms label and change it's properties inside the thread function?

Related

Delphi: form as passive UI during externally controlled processing

In a Delphi forms app, how can I get processing code to execute without user input, and how do I get the UI to update with a given frame rate?
The code in question is a test frame for testing/measuring the concurrent operation of components under heavy load, with multiple processes on the same or different machines. The focus is mostly on database operations (peer-to-peer or server-based) and filesystem reliability/performance with regard to file and byte range locking, especially over the network with heterogeneous client OSes.
The frame waits for external events (IPC, file system, network) that signal start and stop of a test run; after the start signal it calls the provided test function in a tight loop until the stop signal is received. Then it waits for the next start signal or the signal to quit.
I've been doing similar things in FoxPro for ages. There it is easy because the Fox doesn't have to sit on a message pump like Delphi's Application.Run(); so I just put up a non-modal form, arrange for it to be refreshed every couple hundred milliseconds and then dive into the procedural code. In raw Win16/Win32 it was slightly less easy but still fairly straightforward.
In Delphi I wouldn't even begin to know where to look, and the structure of the documentation (D7+XE2) has successfully defied me so far. What's the simplest way to do this in Delphi? I guess I could always spin up a new thread for the actual processing, and use raw Win32 calls like RedrawWindow() and PostQuitMessage() to bend the app to my will. But that looks rather klunky. Surely there must be 'delphier' ways of doing this?
Create a background thread to do the processing task. That leaves the main UI thread free to service its message loop as required.
Any information that the task needs to present to the user must be synchronized or queued to the main UI thread. Of course, there's plenty more detail required to write the complete application, but threading is the solution. You can use a high level library to shield yourself from the raw threads, but that doesn't change the basic fact that you need to offload the processing to a thread other than the main UI thread.

Can the TWebBrowser be used in a thread in Delphi without Application.ProcessMessages?

I am trying to create screen captures of web pages in a Delphi server application (XE2) using TWebBrowser. The screen captures are initiated via web service calls to my server, so to preserve scalability, I would like to service the requests without relying on critical sections or Application.ProcessMessages to do the web page rendering.
Can this be done with TWebBrowser?
I've done this already in a number of objects, and sadly enough the TWebBrowser object ties very much into it's parent object, and specifically its HWND handle. (see also TWebBrowser.HandleNeeded)
The best results I've had was by encapsulating the TWebBrowser and form in an ActiveX library, so the 'message pump' behind it is separated from the main application. This way ActiveX/COM handles all threading and synchronization issues.
Try putting the TWebbrowser in a separate exe. That would move that to a different thread/process and you gain modularity, scalability and performance. The web service can communicate with the process that has the webbrowser using IPC or messaging.
Use a queue system to track assignment and completion of capture tasks to the screen capture process or run the exe for each site to capture.
Another advantage you get using this method is if the capture program crashes, the web service would still be available to take requests. The web service can check if the exe process is in memory before assigning a task and if it is not (crashed or not started) it can start the exe on its own.

How best to convert multiple Delphi TTimer background scan tasks using Omnithread

I've started to look at using Omnithread to improve my Delphi Application using multithreading. Creating one or more worker tasks are well covered by the documentation so that long actions that I invoke from button clicks can be replaced by this demo code (Async, CreateTask etc). Where I am having difficulty though is in how to replace my most 'messy' code which operates as follows.
I have a concept of a single class instance that corresponds to a hardware module. The class publishes one or more properties that expose current values and settings for the hardware. Properties might be read only or read / write. For each of these class instances there can be from zero to several display forms visible. A display form has a TTimer and a built list of the aformentioned published properties. This list is iterated to match up suitably named controls such as labels or edit controls and an RTTI mechanism is used to get and set values between the control and its property. The result is a form which provides a nice UI on to the actual hardware module with the side effect than multiple forms can be open, modifying data on one of them causes the others to show that data shortly after. This property monitoring is performed by the TTimer ticking at 300 ms intervals. Each tick causes it to scan through all properties of the class and to refresh the matching control on its form. The timer runs for the lifetime of the open form. Forms are created when needed and then freed (this has the useful performance optimisation that with no forms open to inspect the hardware, the Application must run as fast as possible because no monitoring tasks can be running).
Is there a better way of using threading to access my published properties, rather than using a TTimer in the UI thread? Or would synchronisation issues outweigh any advantages? If threading is useful, how would one create a repeating task such as to emulate the ticking timer?

Delphi COM EXE and Threading

Just want to confirm with the COM/DCOM experts out there...
I have a Delphi COM EXE that is running on a server (threading is Single Apartment) and another copy of that same EXE starts up on the same server
(a server that has say 2 processors with dual core so the task manager shows 4 separate graphs) will they take turns waiting for each other or will they run on separate cores?
I found a post somewhere that said
"If two clients need to use the same object, they have to take turns. With this threading model the instance data is safe, global data must be protected using critical sections or some other form of serialization. Of course, the thread's local variables are reliable across multiple calls."
You've missed the "different objects from the same server" part from the same paragraph. Since you have "Single instancing" you get a separate server for each COM object instance, so calls to those instances can be processed in parallel and COM will not have to provide any mutual exclusion.
Think of it this way. Threading models are there to provide thread safety - synchronized access to data shared between threads of the same process. You have one object per process, so there's no two threads will try to access the same object unless of course you try to pass a pointer to one object into another object method call.

Delphi - Message loop for Form created in DirectShow filter goes dead

I have a DirectShow filter created with Delphi Pro 6 and the DSPACK direct show library. I'm running under windows XP. I've tried creating the form dynamically when the container class for the DirectFilter has its constructor called, passing NIL into the constructor as the AOwner parameter (TMyForm.Create(nil) and then calling the Form's Show() method. The form does show but then appears to stop receiving windows messages because it never repaints and does not respond to input. As a test I then tried creating my own WndProc() and overriding the Form's WndProc(). My WndProc() did get called once but never again.
I'm guessing it's because I'm a DLL and the context that I am running in is not "friendly" to the window message handler for the form; perhaps something to do with the thread that calls it or whatever. If someone could give me a tip on how to solve this or what the proper way to create a persistent window is from the context of a DirectShow filter I'd appreciate it. Note, as I said the window needs to be persistent so I can't create it as a Filter property page.
Thanks,
Robert
I can't help you with the DirectShow filter specifics, but I feel that some general information about windows and message handling might help.
Windows have thread affinity, which means that all messages for a window will be handled in the context of the thread that created it. That means that this thread needs to have the standard message processing loop, the low level equivalent of Application.ProcessMessages(). Both messages from the same and from other threads will be queued in the message queue of the creating thread, and the message loop will get them, (optionally) translate them, and dispatch them to the window handler of the target window.
What you are describing could be caused by either
not having a message processing queue in the thread that creates the window, or
creating the window in the wrong thread
(Note that these are essentially the same, but stated like this it becomes apparent that there may be different problems that cause this, which need to be fixed in different ways - either the window needs to be created in a different thread, or a processing loop needs to be created in the thread.)
You need to find out which of the two causes your window not to process messages. You don't necessarily need to override WndProc(), message handling methods for distinct messages will work (or not work) the same. That your WndProc() was called once doesn't really tell you much, because under some circumstances messages sent from the same thread will be handled without the message loop, by calling the window proc directly.
Since your filter resides in a DLL I don't think that creating your own message loop would be the right thing. This works for a modal dialog, which will be created, the message loop will run until the dialog is closed, and then the message loop will terminate and the DLL function will return. It will not work for a DLL exported function that will be called and needs to return all while the message loop is still running. I assume the framework that creates and calls those filters will handle the message loop as well. However, that is a gut feeling, not knowing about DirectShow filters this may well be wrong.
What might help you to debug this is a tool like Spy++ from Visual Studio, with which you can show information about windows, log messages sent to them or to all windows in the same process or thread, show window hierarchies and do a lot of other interesting things. If you don't have that, there are a lot of clones (some freeware) on the net, which Google should turn up. Trying to show the messages sent to all windows of the same thread or process should tell you whether a message loop is running. You should also be able to get more information by running SysInternals Process Explorer or similar tools.

Resources