Threads vs. GUI in VB - vb.net

The language I am talking about is VB.
I'm struggling with this problem for over three weeks, and still a solution is not in sight.
The problem is the following:
I have got an intense calculation running in a sub procedure, while modifying the GUI a lot in the process. After a short period of time, the application freezes and is "not responding". After the calculation is finished, everything suddenly snaps to the point I have modified it. Nothing special about that.
But if I now try to start the sub with a thread, so the application doesn't freeze anymore, I can't access the GUI, because "it isn't created by the thread itself".
How do I get around this??
More concretely: How do I access information about the GUI (especially width and height of a PictureBox) and modify the GUI (especially setting a BackgroundPicture in a PictureBox)?
Any help is appreciated. Thank you!

You need to read up on how to use the Dispatcher (MSDN Threading Model)
If only one thread can modify the UI, how do background threads interact with the user? A background thread can ask the UI thread to perform an operation on its behalf. It does this by registering a work item with the Dispatcher of the UI thread. The Dispatcher class provides two methods for registering work items: Invoke and BeginInvoke. Both methods schedule a delegate for execution. Invoke is a synchronous call – that is, it doesn’t return until the UI thread actually finishes executing the delegate. BeginInvoke is asynchronous and returns immediately.
Small snippit of code from example in msdn article link:
startStopButton.Dispatcher
.BeginInvoke(DispatcherPriority.Normal,
New NextPrimeDelegate(AddressOf CheckNextNumber))

Related

Pyqt5 how to parallel QWidget creations

In my project it is necessary to display a lot of data at once in the mainwindow of my application.
Now I am not quite sure how to implement any parallelization into qt since qt does not allow modification from any other thread than the "main thread" to change ui elements.
Currently I do have only one for loop in my setup function and this creates my QGroupBox object on demand. I already tried to take the work load to other cores, but pickle was not able to process my mainwindow. My other experiment was to start a thread which generates all my QGroupBox for me and send this object via signal back to the "main thread". Also not successful, since addWidget failed because the object was created in another thread with another parent apparently. This confuses me, than the thread has the parent instance of the "main thread" or am I wrong here?

VB.NET: What happens if I run CPU-bound code using Await?

I am trying to understand async/await. I understand that you should not Await a CPU-bound method, but to help my understanding I am curious what happens if you do. Consider:
Public Async Function DoSomeTasks()
Await LongRunningCPUBoundMethod1()
LongRunningCPUBoundMethod2()
End Function
Public Async Function LongRunningCPUBoundMethod1() As Task
' Do stuff synchronously
End Function
Public Sub LongRunningCPUBoundMethod2()
' Do stuff synchronously
End Sub
How will the Task Scheduler handle the CPU resources? In what order will these methods execute? Will LongRunningCPUBoundMethod1 or LongRunningCPUBoundMethod2 execute first?
The thing to remember here is that Async/Await code is not necessarily multi-threaded. You can use them to help with multi-threaded code by awaiting items that start a separate thread, but what they really do is allow you to break up several tasks efficiently in the same thread.
This doesn't come without some overhead; switching between asynchronous tasks has a cost. When you await cpu-bound tasks, you've added that cost to the already cpu-intensive work, and therefore made things worse rather than better. However, if you combine this with code that starts the cpu-heavy tasks in a separate thread, and then uses a WaitHandle or a Task to send the results back, you might be fine again (depending on how many items you're awaiting relative to the number of available cores), because now you're taking advantage of the multiple cores in your CPU.
Additionally, let's look at this in context of .Net WinForms. It's important to remember here that you never want to do significant CPU work on main UI thread. Really, anything that blocks for more than a few milliseconds is problematic. If that thread is busy, the Windows Message pump doesn't run, you can't respond to events, and your user interface becomes unresponsive.
To understand Await in this context, think of it as if it breaks your method up into two parts (or more, if there is more than one Await). Everything up to and including the line with Await runs immediately, and everything after the await is hidden away by the compiler in a new callback method (called a continuation) that will be called with the same context (including variables local to the original method) and in the same thread when the Await has finished.
With this information, it should be clear that if you directly Await a cpu-bound method, you're still doing that work immediately on the UI thread, and your user interface is still in trouble. However, you can again account for this by starting the cpu-bound method in it's own thread. Await, in conjunction with Tasks, make this relatively easy to do without having to write a lot of new code. Certainly it's much better than the old DoEvents() technique.
Order of execution.
1.) LongRunningCPUBoundMethod1()
2.) LongRunningCPUBoundMethod2()
Heres how you could mess with the program flow and excution
var task = LongRunningCPUBoundMethod1();
LongRunningCPUBoundMethod2();
var result = await task;
// now result contains what was returned by LongRunningCPUBoundMethod1()
Sorry, I dont know how await/async affects CPU resources.

GUI Dialog on a separate thread

are there any objects when running wxWidget's common dialogs on a separate thread? I'm developing a browser plugin and so I need to put lengthy operations outside the main browser thread.
I did a small test and it seems to work but a warning appears:
....\src\msw\dirdlg.cpp(333): 'CoCreateInstance(CLSID_FileOpenDialog)' failed with error 0x800401f0 (coInitialize has not been called.).
Does that mean I have to call wxApp::Initialize(...) or some other functions?
Thanks,
Christian
You just need to call CoInitialize() in each thread where you are using COM. So before creating common dialog objects just call CoInitialize() (one per thread) and in the end of thread call CoUninitialize().
For main thread wxWidgets does this internally. For other threads you'll need to call these functions manually. It is generally not related to GUI but related to COM objects which wxWidgets uses internally.
Yes, there are 'objections'
Important notes for multithreaded applications
When writing a multi-threaded application, it is strongly recommended
that no secondary threads call GUI functions.
http://docs.wxwidgets.org/trunk/overview_thread.html

Using CoreDispatcher::RunAsync from a legacy background thread

I am porting a regular C++ app to metro in C++ using WRL. I have an existing thread pool and that some point I need to update the UI from one of these threads.
Touching directly the UI objects gives the expected RPC_E_WRONG_THREAD so I need somehow to execute in the right thread. Looking in MSDN I discovered that the metro dispatcher (CoreDispatcher) has a RunAsync method.
Larry Osterman sort-of answers the question of how to use it here:
Run code on UI thread in WinRT
But what is not clear is if I can do that from a non-winrt thread, that is from a thread which has not called RoInitialize.
I guess to be more precise I fear that the dispatcher might belong to an STA and I would need to somehow marshal the interface so it would be safe to call from my other thread.
Note that the main() function of my app following the msdn samples calls RoInitialize(RO_INIT_MULTITHREADED).
You should be ok calling CoreDispatcher::RunAsync from a non UI thread. But there are a couple of caveats:
1) You need to be in a metro style app (this should go without saying). The reason is that the application object creates an MTA that lives for the life of the application. There's this nifty feature of COM called the implicit MTA - if the MTA exists in your process any threads are considered to be a part of that MTA even if they've not called CoInitialize.
That means that when you access CoreDispatcher::RunAsync, even if you need to proxy objects, the MTA is active so the marshaling should succeed.
Note that there is a period of time during app startup where it's possible that the application object hasn't yet been created - you should refrain from doing anything until your application's code has been executed.
2) You need to capture the CoreDispatcher object on the UI thread you want to use. This is made easier by the fact that the Xaml infrastructure already captures the dispatcher in DependencyObject. So if you already have a Xaml UI element, you can just call .Dispatcher.RunAsync().
PS: The UI thread is on an ASTA (application STA, a new kind of apartment added in Win8) but the dispatcher is thread agile. Note that while the dispatcher is agile, the CoreWindow should not be considered agile.

Is it possible to access the My.Application object from a Form or Control object?

I have a solution with several Projects in it. There is a Windows App project (called ImportClient), and a Class Library (Import.Library). The Import.Library has functions to perform data imports (I have other applications in the solution that also need to call it). But the interactive application, I want to be able to pass in some form controls, and have it update the GUI. No problem. But, I also want to execute a DoEvents() so that the loop execution doesn't hang other interaction to the app.
So, ImportClient has a reference to Import.Library. But I can't add a reference to ImportClient to the Import.Library, because the compiler complains about circular reference, etc. I don't know how else to define the My.Application object of ImportClient as a parameter to the data function in ImportLibrary.
(I realize this is a dumb question - problem is, for this project I have a tight timeline, and haven't learned how to do the BackgroundWorker process. If you think I could pick it up quickly, I'm open to some hints about how to update the progress bar on the GUI, and how to pause / cancel the background task.)
Application.DoEvents is a static method, you don't need an instance of Application to call it, so why not simply add a reference to System.Windows.Forms to access it?
I'd thoroughly recommend finding the time to learn about threading and asynchronous operations, Application.DoEvents is not the silver bullet for keeping your UI smooth...