My Windows application has a tabbed interface. Every tab will render some UI stuff. As everyone knows, if I do a very time consuming for-loop in the main thread without let other to process any Windows messages, the application will be frozen. During the frozen period, I cannot switch tabs.
I was inspired by the multiple process architecture of Google Chrome. I try to use SetParent to embed a process into another process. To be more specific: Process A is the master. It can create unlimited worker processes. Every worker process has its own message loop. If process B is frozen, process A and any other worker processes should not be frozen.
Actually I am wrong: If I click a button worker process B to do a lot of UI stuff in main thread without a break, not only the UI of process B but also the UI of process A will be blocked, until my test code ends.
Can somebody share some lights to me?
What you are attempting to do is, er, tricky to get right. I suggest that you start by reading Raymond Chen's article: Is it legal to call have a cross-process parent/child or owner/owned window relationship
Creating a cross-thread parent/child or owner/owned window relationship implicitly attaches the input queues of the threads which those windows belong to, and this attachment is transitive: If one of those queues is attached to a third queue, then all three queues are attached to each other. More generally, queues of all windows related by a chain of parent/child or owner/owned or shared-thread relationships are attached to each other.
This is exactly the scenario that you describe. And the fusing of all the message queues is to be expected. The fact that you have multiple processes doesn't change the fact that you must not block UI threads.
So I think that your program design is flawed. You are adding an epic amount of complexity, with no reward. The benefits of a multi-process architecture are security and isolation. You don't change anything with regards to blocking UI threads. The only way to solve your problem is to put the long running task on a non-UI thread. My strong advice is to return to a single process design.
Related
I'm working on a simulation model that iterates over time steps. At times when the model results start to go South, I want to be able to click on a button to halt the iteration. However, if my testing is correct, when the iteration is running in the UI thread, the Button.Click event is not actuated because the thread is busy iterating. Is that correct? Is there a way to interrupt the UI thread with a button click when the thread is really busy?
One way to handle this problem is to create a Task using the Task Parallel Library to do the computationally-heavy iterations. I'm starting to work on this approach in case there is no way to interrupt the UI thread but I thought I'd check here to make sure I'm not missing a simpler approach.
The problem with your idea to interrupt your calculations on the UI thread is that it requires the cooperation of the UI thread, which is already slammed doing your calculating. For the UI thread to be able to process your button click the calculating needs to stop so the thread can go back to processing UI events. That means saving your progress so you can pick up where you left off later.
This kind of pausing and resuming seems likely to be more trouble than spinning the computation off into its own thread, it is not totally undo-able (the Netscape browser that JWZ developed worked like this, in a single thread), but the reason the multithreaded approach is encouraged is because it's the way that requires the least work, and keeps your calculation code the most focused on the domain and the least chopped up.
If you put the computation in its own thread then the UI thread will be responsive, the OS will make sure both threads get to run. You can make the calculation check for interruption periodically, you can have a progress bar with a cancel button, and you won't have to worry about stopping work to process UI events.
I'm assuming a UI where you have a single event dispatch thread that is responsible for handling UI events. This is how Swing works in Java and it's a popular choice for lots of GUI toolkits because multithreaded solutions are susceptible to deadlocks (events coming from the user will acquire locks in a different order than events coming from the back end). You can specify tags for language and platform to get more relevant answers.
Ok, here we go.
recently I got fond of HCI topics on interface design.
I found out that there could be some way to implement a multithread interface in case for reducing the delay of system respons.
Morover. this may also be possible to say that designing a user interface has tight relationship with STD.
therefore, I wonder if there is any method or techniques to find independant part of ,say,a given STD of a UI that can be seen as threads?
A multi threaded interface in most cases is not fundamentally different to it's single threaded counterpart. There is still a single thread listening on interface events and it will still run handlers as events happen. However the difference comes down to what is contained in these handlers. A simple single threaded event loop would look as below:
A multi-threaded UI is a little different but the principal is the same:
Effectively long processes which are initiated in worker threads which can then report back to them main UI thread so it can report completion.
In relation to a State Transition Diagram, multi-threading complicates things somewhat however there a number of ways to still accomplish this. The first is to simply map each (potential) thread's path separately, this requires decisions for if any threads are finished at the points the main thread checks. It is also possible to use a thread state transition diagram which can demonstrate many threads in a single diagram but is sometimes harder to parse.
Now regarding using a state transition diagram to help implement threading in a user interface program you simply have to locate tasks between the event handler and returning to listening which are time consuming and likely to block. You then need to dispatch these tasks as a thread, optionally adding a completion callback in the main thread.
If I have missed anything please comment below, otherwise I hope this is helpful.
I would like to have three threads in a sample application.
Thread #1 (Main Thread) - User Interface/GUI
Thread #2 - Tied to a serial port device receiving data via events passing to a data queue.
Thread #3 - Activated when a queue entry is made, process data node, frees data object.
The goal is to
a) Prevent the loss of data when a button or the form is held by the mouse on the main form.
b) Quickly get the data from the event, stuff it in the queue, go back to sleep
c) Process data when we have it, otherwise sleep.
Can packages like AsyncoPro tie event handling to a non-main thread?
I've never done much with serial port event driven apps, most of what I've work with are polled and I want to do some testing.
You can definitely tie event handling to a non-main thread. What you can't do is tie screen updating to a non-main thread. The Windows API is not threadsafe, and so the Delphi VCL, which is built on top of the Windows API, isn't either. But your design is basically a good, workable idea; just remember to use the Synchronize or Queue methods of TThread to send any UI updates back to be executed on the main thread.
The easiest should be to define some user messages, then sent it from sub-threads to the main thread.
It's perfectly thread-safe, and even process-safe.
Use PostMessage() with the Handle of the main form. But don't broadcast this WM_USER+n message to the whole UI, because you could confuse some part of the VCL which defines its own custom messages.
If you want to copy some textual data accross threads or processes, you can see WM_COPY_DATA. In practice, this is very fast, faster than named pipes for small messages.
For User Interface, I discovered than a stateless implementation is sometimes a good idea. That is, you don't call-back the main thread via a Synchronize() call or a GDI message, but your main GUI thread has a timer which check a shared memory buffer for pending updates. This is how the web works, and in practice, it's pretty easy to work with: you don't have to write any callback, each thread is independent, do its own stuff, and refresh when necessary.
But of course, the solution depends on your exact project architecture.
For a simple but proven library, see AsyncCalls, working from Delphi 5 up to XE. For latest versions of the IDE (Delphi 2007 and later), take a look at OmniThreadLibrary. By using such libraries, you'll ensure that your software implementation won't break anywhere: it's very common for a multi-threaded application to work as expected most of the time, then, for unknown reasons, going into an endless loop. And, of course, it happens only on the customer side, not yours... If you don't want to spend hours debugging your program, just trust those proven libraries, which are known to be well designed and debugged.
Sure you can do this, one way or another. Not used Apro since D5 - the Apro I have does not work on my D2009, (unicode/string/ANSIstring issues), & I have my own serial classes. Most of the available serial components have the option of firing dataRx events on either the rx thread or the main GUI thread - obviously in your case you should select the rx thread, (Thread #2). Shove the rx data into some buffer class and push it onto a producer-consumer thread to (Thread #3). Process it there. If you need to do a GUI update from there, PostMessage the reference to the GUI thread and handle it in a user-defined message-handler procedure.
Done this sort of stuff loadsa times - it will work OK.
Rgds,
Martin
I am creating an app that accesses a database. On every database access, the app waits for the job to be finished.
To keep the UI responsive, I want to put all the database stuff in a separate thread.
Here is my idea:
The db-thread creates all database components it needs when it is created
Now the thread just sits there and waits for a command
If it receives a command, it performs the action and goes back to idle. During that time the main thread waits.
the db-thread lives as long as the app is running
Does this sound ok?
What's the best way to get the database results from the db-thread into the main thread?
I haven't done much with threads so far, therefore I'm wondering if the db-thread can create a query component out of which the main thread reads the results. Main thread and db thread will never access the query at the same time. Will this still cause problems?
What you are looking for is the standard data access technique, called asynchronous query execution. Some data access components implement this feature in an easy-to-use manner. At least dbGo (ADO) and AnyDAC implement that. Lets consider the dbGo.
The idea is simple - you call the convenient dataset methods, like a Open. The method launches required task in a background thread and immediately returns. When the task is completed, an appropriate event will be fired, notifying the application, that the task is finished.
The standard approach with the DB GUI applications and the Open method is the following (draft):
include eoAsyncExecute, eoAsyncFetch, eoAsyncFetchNonBlock into dataset ExecuteOptions;
disconnect TDataSource.DataSet from dataset;
set dataset OnFetchComplete to a proc P;
show "Hello ! We do the hard work to process your requests. Please wait ..." dialog;
call the dataset Open method;
when the query execution will be finished, the OnFetchComplete will be called, so the P. And the P hides the "Wait" dialog and connects TDataSource.DataSet back to the dataset.
Also your "Wait" dialog may have a Cancel button, which an user may use to cancel a too long running query.
First of all - if you haven't much experience with multi-threading, don't start with the VCL classes. Use the OmniThreadLibrary, for (among others) those reasons:
Your level of abstraction is the task, not the thread, a much better way of dealing with concurrency.
You can easily switch between executing tasks in their own thread and scheduling them with a thread pool.
All the low-level details like thread shutdown, bidirectional communication and much more are taken care of for you. You can concentrate on the database stuff.
The db-thread creates all database components it needs when it is created
This may not be the best way. I have generally created components only when needed, but not destroyed immediately. You should definitely keep the connection open in a thread pool thread, and close it only once the thread has been inactive for some time and the pool disposes of it. But it is also often a good idea to keep a cache of transaction and statement objects.
If it receives a command, it performs the action and goes back to idle. During that time the main thread waits.
The first part is being handled fine when OTL is used. However - don't have the main thread wait, this will bring little advantage over performing the database access directly in the VCL thread in the first place. You need an asynchronous design to make best use of multiple threads. Consider a standard database browser form that has controls for filtering records. I handle this by (re-)starting a timer every time one of the controls changes. Once the user finishes editing the timer event fires (say after 500 ms), and a task is started that executes the statement that fetches data according to the filter criteria. The grid contents are cleared, and it is repopulated only when the task has finished. This may take some time though, so the VCL thread doesn't wait for the task to complete. Instead the user could even change the filter criteria again, in which case the current task is cancelled and a new one started. OTL gives you an event for task completion, so the asynchronous design is easy to achieve.
What's the best way to get the database results from the db-thread into the main thread?
I generally don't use data aware components for multi-threaded db apps, but use standard controls that are views for business objects. In the database tasks I create these objects, put them in lists, and the task completion event transfers the list to the VCL thread.
Main thread and db thread will never access the query at the same time.
With all components that load data on-demand you can't be sure of that. Often only the first records are fetched from the db, and fetching continues after they have been consumed. Such components obviously must not be shared by threads.
I have implemented both strategies: Thread pool and adhoc thread creation.
I suggest to begin with the adhoc thread creation, it is simpler to implement and simpler to scale.
Only move to a thread pool if (with careful evaluation) (1) there is a lot of resources (and time) invested in the creation of the thread and (2) you have a lot of creation requests.
In both cases you must deal with passing parameters and collect results. I suggest to extend the thread class with properties that allow this data passing.
Refer to the documentation of the classes, components and functions that the thread use to make sure they are thread safe, that is, they can be use simultaneously from different threads. If not, you will need to synchronize the access. In some cases you may find slight differences regarding thread safety. As an example, see DateTimeToStr.
If you create your thread at start and reuse it later whenever you need it, you have to make sure that you disconnect the db components (grid..) from the underlying datasource (disableControls) each time you're "processing" data.
For the sake of simplicity, I would inherit TThread and implement all the business logic in my own class. The result dataset would be a member of this class and I would connect it the db aware compos in with synchronize.
Anyway, it is also very important to delegate as much work as possible to the db server and keep the UI as lightweight as possible. Firebird is my favourite db server: triggers, for select, custom UDF dlls developed in Delphi, many thread safe db components with lots of examples and good support (forum) : jvUIB...
Good Luck
I don't want multiple windows, each with its own UI thread, nor events raised on a single UI thread, not background workers and notifications, none of that Invoke, BeginInvoke stuff either.
I'm interested in a platform that allows multiple threads to update the same window in a safe manner. Something like first thread creates three buttons, the second thread another five, and they both can access them,change their properties and delete them without any unwanted consequences.
I want safe multi-threaded access to the UI without Invoking, a platform where the UI objects can be accessed directly from any thread without raising errors like "The object can only be accessed from the thread that created it". To let me do the synchronizing if I have to, not prevent me from cross-tread accessing the UI in a direct manner.
I'm gonna get down voted but ... Go Go Gadget Soapbox.
Multi threaded GUI are not possible in the general case. It has been attempted time and time again and it never comes out well. It is not a coincidence that all of the major windowing frameworks follow the single threaded ui model. They weren't copying each other, it's just that the constraints of the problem lead them to the same answer. Many people smarter than you or i have tried to solve this.
It might be possible to implement a multi-thread ui for a particular project. I'm only saying that it can't be done in the general case. That means it's unlikely you'll find a framework to do what you want.
The gist of the problem is this. Envision the gui components as a chain (in reality it's more like a tree, but a chain is simple to describe). The button connects to the frame, connects to the box, connects to the window. There are two source of events for a gui the system/OS and the user. The system/OS event originate at the bottom of the chain (the windowing system), the user event originate at the top of the chain (the button). Both of these events must move through the gui chain. If two threads are pushing these events simultaneously they must be mutex protected. However, there is no known algorithm for concurrently traversing a double linked list in both directions. It is prone to dead lock. GUI experts tried and tried to figure out ways to get around the deadlocking problem, and eventually arrived at the solution we use today called Model/View/Controller, aka one thread runs the UI.
You could make a thread-safe Producer/Consumer queue of delegates.
Any thread that wants to update a UI component would create a delegate encapsulating the operations to be performed, and add it to the queue.
The UI thread (assuming all components were created on the same thread) would then periodically pull an item from the queue, and execute the delegate.
I don't believe a platform like that exists per se
There is nothing stopping you from saying taking .Net and creating all new controls which are thread safe and can work like that(or maybe just the subset of what you need) which shouldn't be an extremely large job(though definitely no small job) because you can just derive from the base controls and override any thread-unsafe methods or properties.
The real question though is why? It would definitely be slower because of all the locking. Say your in one thread that is doing something with the UI, well it has to lock the window it's working on else it could be changed without it knowing by the other thread. So with all the locking, you will spend most of your drawing time and such waiting on locks and (expensive) context switches from threads. You could maybe make it async, but that just doesn't seem safe(and probably isn't) because controls that you supposedly just created may or may not exist and would be about like
Panel p=new Panel();
Button b=new Button();
WaitForControlsCreated(); //waits until the current control queue is cleared
p.Controls.Add(b);
which is probably just as slow..
So the real question here is why? The only "good" way of doing it is just having an invoke abstracted away so that it appears you can add controls from a non-UI thread.
I think you are misunderstanding how threads really work and what it takes to actually make an object thread safe
Accept that any code updating the GUI has to be on the GUI thread.
Learn to use BeginInvoke().
On Windows, Window handles have thread affinity. This is a limitation of the Window manager. It's a bad idea to have multiple threads accessing the same window on Windows.
I'm surprised to see these answers.
Only the higher level language frameworks like C# have thread restrictions on GUI elements.
Windows, at the SDK layer, is 100% application controlled and there are no restrictions on threads except at insignificant nitty gritty level. For example if multiple threads want to write to a window, you need to lock on a mutex, get the device context, draw, then release the context, then unlock the mutex. Getting and releasing a device context for a moment of drawing needs to be on the same thread... but those are typically within 10 lines of code from each other.
There isn't even a dedicated thread that windows messages come down on, whatever thread calls "DispatchMessage()" is the thread the WINPROC will be called on.
Another minor thread restriction is that you can only "PeekMessage" or "GetMessage" a window that was created on the current thread. But really this is very minor, and how many message pumps do you need anyway.
Drawing is completely disconnected from threads in Windows, just mutex your DC's for drawing. You can draw anytime, from anywhere, not just on a WM_PAINT message.
BeOS / Haiku OS
Based on my guessing of your requirement, you want a single Windows Form and having ways to execute certain routines asynchronously (like multi-threading), yes?
Typically (for the case of .NET WinForms) Control.Invoke / Control.BeginInvoke is used to a certain effect what I think you want.
Here's an interesting article which might help: http://www.yoda.arachsys.com/csharp/threads/winforms.shtml