SpriteKit windows do not redraw until "applicationDidFinishLaunching" method quits - multithreading

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

Related

How to run one function in another thread

I'm standing in front of a small (maybe not) problem. I have one function which parses XML file (very big xml ~1Gb) so it takes many time (5-6 mins to finish the func). I don't want to use it in GUI-thread because of known issues (mainwindow freezes and nothing happened, so user thinks everything goes wrong). I've tried to solve this problem by using
QtConcurrent::run
But one more problem appeared: if user press X (close button in top right corner) main GUI-thread goes down, but child-thread which was generated my QtConcurrent::run continue his work and I can kill him only by task manager.
I've decided to use QThread instead of QtConcurrent::run6 but I don't understand how can I run MainWindow class function:
void MainWindow::parseXML()
I've tried to create smth like this:
class pThread : public QThread
{
Q_OBJECT
private:
void run();
};
void pThread::run(){
MainWindow::parseXML();
}
But when I'm trying to compile it error appears:
cannot call member function 'void MainWindow::parseXML()' without object
Moreover, I don't know if it possible to update GUI-thread through this method (parseXML function changes statusBar)
What should I do?
The recommended ways to work with threads in Qt is not to inherit from QThread class, see the documentation here and you should be able to do it after that.
And yes it is possible to update the mainwindow from the thread, just code the signals and slots for that functionality, into mainwindow class code a slot that updates the progress and into the class that does the work (the xml parsing you need - there is no reason that functionality should be into the mainwindow class anyway) you code the signal that emit the progress and connect it with mainwindow's slot with Qt::QueuedConnection (note that the default auto-connection will become queued if the objects are in separate threads).
Another option is to use start a QRunnable with QThreadPool. you may want to check documentation. Be ware to wait the spawned threads with QThreadPool::waitForDone().

Silverlight 5: print outside the UI thread?

Is it possible to print in Silverlight without blocking the UI thread?
I have to print a lot of pages, and consequently my UI freezes for a while. I would like to print on a background thread instead (and update a progress bar if possible), but can't figure out how.
I tried calling the Print() method of my PrintDocument inside the DoWork() method of a BackgroundWorker, but that gives me an UnauthorizedAccessException "Invalid cross-thread access".
It seems that even initiating a PrintDocument is not possible outside the UI thread:
PrintDocument pd = new PrintDocument(); in BackgroundWorker.DoWork() throws the same exception.
I found a lot of posts where people say that printing has to happen on the UI thread, but no documentation of this. I'm new to multithreading, so any pointers in the right direction would be appreciated.
I had this problem and came across this question which unfortunately didn't have the answer i was hoping for. But I thought that for anyone else who comes across this problem, this may at least shed some light.
I was following this article on printing in Silverlight, It works like a charm for regular printing on the UI Thread, but for actually trying to print on a separate thread I don't think it's possible. I switched out the last line of code in the example
printDocument.Print("SLPrintDemo document");
with an alternate one to see if it would work
new Thread(() => printDocument.Print("SLPrintDemo document")).Start();
To see if the print job itself would spawn in a separate thread. However though the code compiles and runs fine, the document does not print. The reason seems to be that once the Print command is fired, it then fires up the printing options dialog for choosing printer and other options etc. At this point it is no longer on the UI thread so nothing happens ( No exceptions, so i'm assuming they're swallowed somewhere)
So as far as I can tell at the moment, there is no way to print in Silverlight that is not in the UI thread.
Use Dispatcher for updating your UI. For example:
Dispatcher.BeginInvoke(() =>
{
ProgressBar.Value = 100;
});

WindowFreeze VCL

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.

C++ MultiThreading with visual studio express 2010 Forms 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.

Calling QAxWidget method outside of the GUI thread

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.

Resources