I have a Delphi7 Project with about 10 windows. The MainWindow gets loaded when the program starts. After a while, the MainWindow accesses another window of the project to add listview items and updates them about ever 1-2 seconds. However this window seems to freeze and doesn't show the listview at all after I opened it.
It works if I have in the OnShow Procedure of my MainWindow the following commands:
SecondWindow.Show;
SecondWindow.Close;
It works without problems but it seems unprofessional. Any Ideas how I could draw the window without getting showed?
EDIT: CODE (I use Indy9)
procedure TMainWindow.ServerSocketExecute(AThread: TIdPeerThread);
begin
/....
if Buffer = 'additem' then begin
Window2.ListView1.Items.Add;
Exit;
// .....
end;
end;
That's it. I removed all the timers off Window2 and it seems still to freeze.
Either the mainWindow freezes instantly if an items gets added or when I try to open the 2nd Windows for the first time.
Your problem is that you are calling VCL methods from outside the main GUI thread, i.e. in TMainWindow.ServerSocketExecute. This event executes in a worker thread. Calling VCL/GUI code from a worker thread is simply against the rules of the game. All VCL code must execute in the main GUI thread.
So, solve the problem by making sure that all VCL/GUI code executes in the GUI thread. Use the TIdPeerThread.Synchronize() method, or the TIdSync or TIdNotify class to achieve this.
Thanks to #Remy for supplying the details that I did not know.
Related
I use SpriteKit for Mac OS X (not iOS) to run my programs.
At the end of the "applicationDidFinishLaunching" method of the "AppDelegate"-Class I start all things which are needed for initialization. Some methods do not like to be called from a background-thread like setting window-titles, resizing windows and some other tasks. So all these things are done in the main-thread.
Then we come to my problem: I cannot simply run my main program at the end of the "applicationDidFinishLaunching" method, because when I do so, the "applicationDidFinishLaunching" method does not quit until my main program quits. And my main program does not quit, because it shows some animation on the screen directly after starting the program.
In the case, that the "applicationDidFinishLaunching" method does not quit, SpriteKit does not redraw the window, so my animation runs but I see a white window.
After quitting my program, the "applicationDidFinishLaunching" method quits, too, and I see the last picture of the animation.
So I realized a workaround: I now do the initialization in the "applicationDidFinishLaunching" method and then start a background thread which runs my main program.
The "applicationDidFinishLaunching" quits after starting the background-thread and the window is updated as expected. Everything runs fine with the background-thread doing the animation.
And now the problem, I cound not solve: I need to hide the menu bar, not directly when starting the program, but after some time.
NSMenu.setMenuBarVisible(false)
Doing so is no problem when calling from the main-thread but if I hide the menu-bar from my background thread, then I can hide it once, make it visible once, hide it a second time and when making it visible a second time an exception in the AppDelegate Class stops my program:
Thread 1: EXC_BAD_ACCESS (code=EXC_i386_GPFLT)
My idea to solve this problem, was to post an event, which is handeled by the main-thread. But if I post a keyboard event for example, the event-handling is done within the background-thread, too.
Events like selecting a menu by the user, not programmatically are handeled from the main thread but I did not find a way to post an event which is then handeled in the main thread instead of the thread, which contains the sendEvent-command:
NSApplication.sharedApplication().sendEvent(event!) // Called from background-thread
Has anybody an idea of sending an event which is handeled by the main-thread
or
Running my program completely in the main-thread without having the problem, that the window-content is not drawn at all. This second solution would be my favourite, because there are some more things, which make problems within a background thread.
Perhaps I can start my main program from another method, some time after "applicationDidFinishLaunching" has finished.
Some deeper information to the topic above but still no solution:
I discovered, that there exists a function "performSelectorOnMainThread" which can be called from swift like this:
NSApplication.performSelectorOnMainThread(Selector(myFunctionToCall()), withObject: nil, waitUntilDone: true)
This call compiles, my function is called but in my background thread not on the main thread and an error is dumped:
2015-01-17 20:11:09.142 AudioDatabase[4449:2099588] +[NSApplication (null selector)]: unrecognized selector sent to class 0x7fff7b1d8be0
But execution continues. I was not able to call the function on any other than a few types like NSApplication, NSObject, NSThread like a class function. But I never reached the main loop with this.
Another idea was to use NSInvocation, but when I look in the documentation, only the Objective-C Part appears.
It would help, if it was possible, to simply call a function of mine with or without arguments that runs in the main thread and can do there something.
While running my program in a background thread, I discovered a way, to execute neccessary commands in the main-thread asynchronous. To do so, you have to call:
dispatch_async(dispatch_get_main_queue())
{
// This block runs in the main thread
}
So my question was, so show and hide the menu bar without crashing my program. Here are the finished functions which work, when called from a background-thread:
func m_MenuBarShow ()
{
dispatch_async(dispatch_get_main_queue())
{
NSMenu.setMenuBarVisible(true) // Class func, must be called on the Class (NSMenu) and not on the Instance (NSApp.sharedApp.mainMenu)
}
}
func m_MenuBarHide ()
{
dispatch_async(dispatch_get_main_queue())
{
NSMenu.setMenuBarVisible(false) // Class func
}
}
Please note that there is a small restriction on using this: The block is called asynchronous, that means you have to make sure, that it is finished, until doing something with the result. In the case of showing the menu bar this is no problem. But if you want to do something like opening a file, you must handle this.
I will explain this as an answer to another question of mine. Please have a look at: Open File Dialog crashes in Swift
I have a multi-threaded app, in the thread class there is an FInputImage: VCL.Graphics.TBitmap. I have another image called FImageV: VCL.Graphics.Bitmap.
Check the following code:
...
FImageV.LoadFromResourceName(HInstance, 'IMAGEH');
...
FInputImage.Canvas.Lock;
try
FInputImage.Canvas.CopyMode := cmSrcCopy;
FInputImage.Canvas.Brush.Color := clRed;
FInputImage.Canvas.Rectangle(SR);
FInputImage.Canvas.StretchDraw(SR, FImageV);
finally
FInputImage.Canvas.Unlock;
end;
If I submit more images so more than one thread is running, after a while the StretchDraw does nothing, it disappears. I just see the red rectangle drawn with Rectangle(SR).
This happens randomly. All objects are created and freed inside the thread. I also tried to add the FImageH as a separate class variable, since it is a static image, but the results are the same.
Any ideas why this is happening would be welcome.
Thanks!
Lock the canvas of FImageV too.
I have a thread, called TAlertThread. The thread interacts with its owner by triggering events. For example, when certain data is available inside the thread, it sets some temp variables and calls Synchronize(UpdateAlert) which in turn triggers the appropriate event.
Now the thread works perfectly in any standard windows application. My problem is when I put that thread inside of an ActiveX form (TActiveForm). The ActiveX control (aka COM object) is then embedded inside of a Windows Desktop Gadget (via HTML / Javascript). I also have experience with this, the gadget is not the issue. The ActiveX component works fine in its destination, except the thread is never executed. It's even being called EXACTLY the same way as I called it from the App.
Is this some limitation with ActiveX, blocking threads from executing? I wouldn't think so, because other things that require threads internally (such as TADOConnection) work. I am in fact properly calling CoInitialize and CoUninitialize appropriately. Again, works perfect in an application, but does not work at all in ActiveX.
Here is how I call this thread...
procedure TRMPDashXS.ExecThread;
begin
//Thread created suspended
lblStatus.Caption:= 'Executing Thread...';
fThread:= TAlertThread.Create(fConnStr); //fConnStr = connection string
fThread.Priority:= tpIdle;
fThread.OnConnect:= Self.ThreadConnected;
fThread.OnDisconnect:= Self.ThreadDisconnected;
fThread.OnBegin:= Self.ThreadStarted;
fThread.OnFinish:= Self.ThreadFinished;
fThread.OnAlert:= Self.ThreadAlert;
fThread.OnAmount:= Self.ThreadAmount;
fThread.Resume; //Execute the thread
end;
I suspect this might describe exactly what you're experiencing in your version of Delphi:
http://soft-haus.com/blog/2009/02/10/codegear-borland-activex-threading-synchronization-problems/
which references the same article you cited:
http://edn.embarcadero.com/article/32756
I'm not sure if that helps ... but I hope it does. At least a little :)
PS:
Is there any particular reason you have to use Com/ActiveX and/or TActiveForm?
According to this article here: http://edn.embarcadero.com/article/32756 web browsers don't allow threading via ActiveX. However that still doesn't explain why it doesn't work when I put it in a C# application.
I am developing a Windows forms application which connects to a piece of hardware, acquires a lot of data (~1 GSample/sec), processes it, and spits it out to the screen upon a button click. I am now trying to automate the process in a loop that can be started/stopped at any time so I can monitor it whilst tweaking the input to the acquisition hardware. I thinks it's clear that I need to do this on a separate thread, but I'm having a heck of a time trying to do this in c++/cli - I have found a number of good examples using MFC, which is not supported by Express.
Specifically: My task is to press a button which is handled in Form1.h, to call a function in my main file Acquisition.cpp which contains the following code (currently an infinite loop)
void Form1::realTimeUpdate()
{
// live is a boolean variable set by a button on the form
while(live)
{
displayVariance(getVar(getQuadratures(100),nbrSamples));
}
}
I wish to execute this code in a separate thread so that the main program can listen for the user request to stop the operation. Without threading, I currently have to forcefully quit the program (or set it to run a fixed number of times) to stop it.
Is there any suggestions how I might go about running this code on a separate thread?
I've (unsuccessfully) tried a few things already:
Modifying the example given in This Microsoft Example. Problem: requires /clr:oldSyntax option which is incompatible with the other 1300 lines of code in the program.
Trying to do what I'd do in Java (Declare a global thread and start/stop it from any point in the code. Problem: Compiler won't let me declare a global System::Threading.Thread
this beautiful example. Problem: Requires MFC.
Any suggestions would be greatly appreciated!
You can use a BackgroundWorker or a Thread to handle this. You'll need to make sure that the portion of your work that updates the UI is marshaled back to the UI thread, however.
Here is a tutorial on threading in C++/CLI.
For the record, upon Reed's suggestion about using a BackgroundWorker, I sifted through the code at the bottom of this page and modified my code so that:
It created a new backgroundWorker BGWorker in which BGWorker->DoWork() called my realTimeUpdate() function.
A button on the main Form calls either RunWorkerAsync() or CancelAsync() depending on whether or not the process is running (checked by a boolean flag in my main program).
The realTimeUpdate() function is now passed a BackgroundWorker - realTimeUpdate(BackgroundWorker^ worker, DoWorkEventArgs ^ e) After each calculation is complete within the internal loop, it calls worker->ReportProgress(result) function. In the BGWorker->ProgressChanged() function a separate function, upDataUI(int) draws the result on the main form.
Thanks again for the help.
I'm beginning to wonder if this is impossible, but I thought I'd ask in case there's a clever way to get around the problems I'm having.
I have a Qt application that uses an ActiveX control. The control is held by a QAxWidget, and the QAxWidget itself is contained within another QWidget (I needed to add additional signals/slots to the widget, and I couldn't just subclass QAxWidget because the class doesn't permit that). When I need to interact with the ActiveX control, I call a method of the QWidget, which in turn calls the dynamicCall method of the QAxWidget in order to invoke the appropriate method of the ActiveX control. All of that is working fine.
However, one method of the ActiveX control takes several seconds to return. When I call this method, my entire GUI locks up for a few seconds until the method returns. This is undesirable. I'd like the ActiveX control to go off and do its processing by itself and come back to me when it's done without locking up the Qt GUI.
I've tried a few things without success:
Creating a new QThread and calling QAxWidget::dynamicCall from the new thread
Connecting a signal to the appropriate slot method of the QAxWidget and calling the method using signals/slots instead of using dynamicCall
Calling QAxWidget::dynamicCall using QtConcurrent::run
Nothing seems to affect the behavior. No matter how or where I use dynamicCall (or trigger the appropriate slot of the QAxWidget), the GUI locks until the ActiveX control completes its operation.
Is there any way to detach this ActiveX processing from the Qt GUI thread so that the GUI doesn't lock up while the ActiveX control is running a method? Is there something clever I can do with QAxBase or QAxObject to get my desired results?
After some experimentation, I was able to solve this by doing something I thought I'd tried earlier: creating a new QThread and calling QAxWidget::dynamicCall from the new thread. I must not have coded it correctly the first time I tried this solution; after sitting with a co-worker, we were able to get it to work. To be specific, what we did is:
(Step 1) Created a subclass of QThread to represent the thread I need to call dynamicCall().
(Step 2) In the constructor of my QThread, pass in a pointer to my original QAxWidget, and keep the pointer in a member variable.
MyThread::MyThread(QAxWidget* passedWidget) : QThread()
{
actualWidget = passedWidget;
}
(Step 3) In the run() method of the QThread, call the dynamicCall() method of the QAxWidget.
void MyThread::run()
{
QVariant result = actualWidget->dynamicCall(...parms as necessary...);
}
(Step 4) Back in my main code, when I need to execute dynamicCall(), I just call the start() method of MyThread. The start() method will execute run() in its own thread, thus sending the necessary command to the ActiveX object without blocking or stalling the main GUI thread.
If there is no event loop needed, then there is no need NOT to subclass QThread! I think this is the way to solve this without a bunch of signals to the main thread which (more than likely) owns the QAxWidget. The latest docs for Qt 5.3 referring to QThread also bears this out.