I made function which use do while(true) - infinite loop (which controls other apps)
I am searching solution how to make form accessable - when I start app, access just loading and my form cannot be changed. At least I tried to make some "listening function" for key "S" to stop while and it doesnt work too (maybe I am doing it bad, is it possible?)
I just used
Do While (run) <code> Loop
I guess I will need at least 2 thread (1 thread handle infinite while, 2 thread for form, but I read access cannot handle Multithreading.)
I can ask, is there some possibility of make this work?
Jan.
MS Access or MS office are single threaded platforms and cannot perform parallel executions. Generally, having a blind loop or uncontrolled loop is not a good practice at all. If you have a blind loop function without a controller, you are wasting process cycles of your vba application.
what you can do:
use timer and set intervals how often your code must execute
Add "Do events" within the loop to use the process cycles to execute some other code when a code within loop is waiting for an external signal.
Add any sort of controller to break the loop.. simple if else condition
Migrate your code to an external .DLL and execute/control the function outside VBA
In short, VBA cannot perform threading. Using uncontrolled will freeze your application which will force you to use [CTRL] + F12 to stop the execution manually.
I used function "DoEvents" (it at least react for input - keyboard / mouse)
Related
I have an application that has multiple screens and a process that needs to get UI info from some and update others.
Tried many methods but the result always is always "not a Java FX thread". Without using some kind of thread the UI does not update Because of the multi screen nature of the app (not practical to change) I need to fundamentally change the application architecture which is why I am not posting any code - its all going to change.
What I cant work out is the best way to do this and as any changes are likely to require substantial work I am reluctant to try something that has little chance of success.
I know about Platform.runLater and tried adding that to the updates but that was complex and did not seem to be effective.
I do have the code on GitHub - its a personal leaning project that started in Scala 2 but if you have an interest in learning or pointing out my errors I can provide access.
Hope you have enjoyed a wonderful Christmas.
PS just make the repo public https://github.com/udsl/Processor6502
The problem is not that the Platform.runLater was not working its because the process is being called form a loop in a thread and without a yield the JavaFX thread never gets an opportunity to run. It just appeared to be failing – again I fall foul of an assumption.
The thread calls a method from within a loop which terminates on a condition set by the method.
The process is planned to emulate the execution of 6502 processor instructions in 2 modes run and run-slow, run-slow is run with a short delay after each instruction execution.
The updates are to the main screen the PC, status flags and register contents. The run (debug) screen gets the current instruction display updated and other items will be added. In the future.
The BRK instruction with a zero-byte following is captures and set the execution mode to single-step essentially being a break point though in the future it will be possible via the debug screen to set a breakpoint and for the execution of the breakpoint to restore the original contents. This is to enable the debugging of a future hardware item – time and finances permitting – it’s a hobby after all 😊
It terns out that the JavaFX thread issue only happens when a FX control is written to but not when read from. Placing all reads and writes in a Platform.runLater was too complex which is why I was originally searching for an alternative solution but now only needed it protect the writes is much less a hassle.
In the process loop calling Thread.’yield’() enables the code in the Platform.runLater blocks to be executed on the JavaFX thread so the UI updates without an exception.
The code in the Run method:
val thread = new Thread {
override def run =
while runMode == RunMode.Running || runMode == RunMode.RunningSlow do
executeIns
Thread.`yield`()
if runMode == RunMode.RunningSlow then
Thread.sleep(50) // slow the loop down a bit
}
thread.start
Note that because yield is a Scala reserved word needs to quote it!
It's a very common problem every developer faces every now and then, when visual updates may be so rapid and fast that it causes the contents of the form to flicker. I'm currently using a thread to search files and trigger an event to its calling (main VCL) thread to report each and every search result. If you've ever used the FindFirst / FindNext, or done any large loop for that matter which performs very fast and rapid iterations, then you would know that updating the GUI on every little iteration is extremely heavy, and nearly defeats the purpose of a thread, because the thread then becomes dependent on how fast the GUI can update (on each and every iteration inside the thread).
What I'm doing upon every event from the thread (there could be 100 events in 1 millisecond), is simply incrementing a global integer, to count the number of iterations. Then, I am displaying that number in a label on the main form. As you can imagine, rapid updates from the thread will cause this to flicker beyond control.
So what I would like to know is how to avoid this rapid flicker in the GUI when a thread is feeding events to it faster than it's able to update?
NOTE: I am using VCL Styles, so the flicker becomes even worse.
This is indeed a common problem, not always by threads, but by any loop which needs to update the GUI, and at the same time the loop is iterating faster than the GUI is able to update. The quick and easy solution to this is to use a Timer to update your GUI. Whenever the loop triggers an update, don't immediately update the GUI. Instead, set a some global variable (like the global iteration count) for each thing which may need to be updated (the label to display the count), and then make the timer do the GUI updates. Set the timer's interval for like 100-200 msec. This way, you control the GUI updates to only occur as frequent as you set the timer interval.
Another advantage to this is the performance of your thread will no longer depend on how fast your GUI can update. The thread can trigger its event and only increment this integer, and continue with its work. Keep in mind that you still must make sure you're thread-protecting your GUI. This is an art of its own which I will not cover and assume you already know.
NOTE: The more GUI updates you need to perform, the higher you may need to tweak the timer's interval.
is it possible running one function after another function with 100ms delay in separate thread.
i want to make a function to changing one cell in excel and run another function by 100ms delay by a separate thread in visual basic 6
tnx
You can use API
In your delcarations section add this:
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
To use it:
Sleep 100 ' to sleep for 0.1 second
It's possible by creating an ActiveX exe. See wqw's answer here, To use thread in programming in vb6. The 100ms second delay will be ~100ms delay. Depending on how accurate you want youe delay to be you can use the native VB timer accurate to somewhere arounf 10ms, or for higher resolution you can use a multi-media timer (makes it difficult to debug), or get a control that implements a high resolution timer.
It is possible to do multi threading in VB6, using ActiveX exes. These are "Out of process" so can be loaded and made to return immediately. Its many years since I did this, but I think I may have used a timer to allow me to load the class and return immediately, then have the class carry on working in its process.
This sort of a approach is horrible though - managing it in any sort of sensible way is a nightmare.
A much better option for you would be to write what you want in VB.Net (you should be fine to do it in an Express version I think), and set the assembly up to build to be COM compatible. Then you can reference this functionality in your VBA or whatever.
ActiveX DLL instances also run on their own thread, but all in one process. So, you don't need the additional overhead of interprocess communication. Of course, Excel would run in a separate process anyway.
I'm using 3.9.7 cURL library to download files from the internet, so I created a dynamic bibioteca of viculo. dll written in C using VC + + 6.0 the problem is that when either I call my function from within my vb6 application window locks and unlocks only after you have downloaded the file how do I solve this problem?
The problem is that when you call the function from your DLL, it "blocks" your app's execution until it gets finished. Basically, execution goes from the piece of code that makes the function call, to the code inside of the function call, and then only comes back to the next line after the function call after the code inside of the function has finished running. In fact, that's how all function calls work. You can see this for yourself by single-stepping through your code in the VB 6 development environment.
You don't normally notice this because the code inside of a function being called doesn't take very long to execute before control is returned to the caller. But in this case, since the function you're calling from the DLL is doing a lot of processing, it takes a while to execute, so it "blocks" the execution of your application's code for quite a while.
This is a good general explanation for the reason why your application window appears to be frozen. A bit more technically, it's because the message pump that is responsible for processing user interaction with on-screen elements is not running (it's part of your code that has been temporarily suspended until the function that you called finishes processing). This is a bit more difficult for a VB programmer to appreciate, since none of this nitty-gritty stuff is exposed in the world of VB. It's all happening behind the scenes, just like it is in a C program, but you don't normally have to deal with any of it. Occasionally, though, the abstraction leaks, and the nitty-gritty rears its ugly head. This is one of those cases.
The correct solution to this general problem, as others have hinted at, is to run lengthy operations on a background thread. This leaves your main thread (right now, the only one you have, the one your application is running on) free to continue processing user input, while the other thread can process the data and return that processed data to the main thread when it is finished. Of course, computers can't actually do more than one thing at a time, but the magic of the operating system rapidly switching between one task and another means that you can simulate this. The mechanism for doing so involves threads.
The catch comes in the fact that the VB 6 environment does not have any type of support for creating multiple threads. You only get one thread, and that's the main thread that your application runs on. If you freeze execution of that one, even temporarily, your application freezes—as you've already found out.
However, if you're already writing a C++ DLL, there's no reason you can't create multiple threads in a VB 6 app. You just have to handle everything yourself as if you were using another lower-level language like C++. Run the C++ code on a background thread, and only return its results to the main thread when it is completely finished. In the mean time, your main thread is free.
This is still quite a bit of work, though, especially if you're inexperienced when it comes to Win32 programming and the issues surrounding multiple threads. It might be easier to find a different library that supports asynchronous function calls out-of-the-box. Antagony suggests using VB's AsyncRead method. That is probably a good option; as Karl Peterson says in the linked article, it keeps everything in pure VB 6 code, which can be a real time saver as well as a boon to future maintenance programmers. The only problem is that you'll still have to process the data somehow once you obtain it. And if that's slow, you're right back where you started from…
Check out this article, which demonstrates how to asynchronously transfer large files using a little-known method in user controls.
I wrote a function that does alot of mathematical operations and it takes about 10 minutes to finish its work. I tried to call this function via a button on a form (Windows forms application). But the problem now is during the 10 minutes, the main form stops to respond till the function is finishing its work.
How can i solve this... any idea!
You might assign a new thread for the calculations so that the form would not have to wait for the calculation to finish to continue execution (i.e. listening to and responding to events etc.)
The problem is that, while your 10 minute function is working, the rest of the program is not executed. In particular, it cannot execute the rendering. (i.e. making your form respond).
The solution is to use threads.
As already mentioned you should assign long running tasks to a worker thread or a threadpool thread.
Keep in mind that there are limited numbers of threadpool thread. ALso Windows forms is not thread safe so you should not be directly updating the form from the created thread. You can make use of InvokeRequired.
In this case better to use BackgroundWorker class. Details in following link.
http://stuff.seans.com/2009/05/21/net-basics-do-work-in-background-thread-to-keep-gui-responsive/