Jump to content

Dalija Prasnikar

Members
  • Content Count

    496
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Dalija Prasnikar

  1. Dalija Prasnikar

    Delphi 10.4.2 Professional

    As long as we have power, all is good
  2. Dalija Prasnikar

    Delphi 10.4.2 Professional

    You can also try disabling package cache, it helped in my case. You need to edit registry key HKEY_CURRENT_USER\SOFTWARE\Embarcadero\BDS\21.0\Package Cache and then set the DisableAll value to 1. If it does not exist add new DWORD value with that name. But 10-12 seconds is really long time. Maybe something else is in play. If disabling Live Bindings and package cache does not help I would recommend filing bug report at https://quality.embarcadero.com/
  3. Dalija Prasnikar

    TLightweightMREW considerations

    Locks of any kind used as field in a class are meant to protect integrity of the data inside object instance, not to protect that instance from being destroyed. If you need to protect particular TMyClass instance itself, you will need to use some outer locking mechanism.
  4. Dalija Prasnikar

    Several F2084 Internal Error on Delphi 10.4.2

    The most similar would be Delphi XE, but that is not a long jump 🙂 Every new version has some features and some differences, and you will need to tweak some code to adjust in order to benefit from those features. The more recent version you use, the less future tweaking will be required. From that perspective, probably the most stable recent version is Tokyo - 10.2.3. Rio - 10.3.3 is also quite usable, but it does have less stable debugger, and new IDE styling can cause performance issues on low end machines. All those versions have better support for using high DPI in your applications. If high DPI is not imperative for you, and you are less inclined to make huge jump, then XE7 is probably the most stable version in between. XE7 is also good option if your code uses class helper for gaining access to private class members, since that was removed in Berlin 10.1.
  5. Dalija Prasnikar

    Several F2084 Internal Error on Delphi 10.4.2

    While 10.4.2 is a bit unstable (fortunately, my code does not choke it too often), going down to D2010 seems like overkill. There are many stable releases in between you can productively work with, and then move to 10.4.2 when patched.
  6. OK, long timeout was a bit confusing and I could not determine how long each operation should last. As far as I can see there are no obvious reasons why your approach fails with timeout. It is a bit longish code, so I am not excluding possibility of not catching error in code and possibility of some memory corruption, but that would commonly show much sooner. Using TTask and reusing threads through its thread pool is definitely faster and more correct approach comparing to creating anonymous threads. Anonymous threads was "fallback" suggestion in case your overall time spent in calculation is long enough so that creating thread overhead pays off. If the TTask is really the issue here (which is also hard to say) another option would be trying some other library. One thing you probably can confirm, by using anonymous threads is that TTask is the culprit here (even though you can never say that with 100% certainty).
  7. Since, your timeout is quite large, I suppose your requirement is not real-time resizing. In that case AnonymousThread approach can be good enough. I would also suggest using TTask wait without timeout, but 10 seconds is quite long time period, so it is quite possible there are other problems with TTask, and that using no timeout would just hang indefinitely (it might be worth trying, though). If the AnonymousThread approach is not good enough (creating and starting thread takes time - not much, but still) then creating reusable dedicated threads that would take care of resampling could be an option. But that is the most complicated approach, because you would need to communicate back and forth with such long running threads and pass data in and out as it finishes processing pieces of data. It is possible that there are libraries that have something you can reuse - the first place I would look for is OmniThreadLibrary https://github.com/gabr42/OmniThreadLibrary
  8. Without going into the why you are getting timeout, could be the issue @Vandrovnik mentioned, could be something else. Depends on your machine, number of cores, system activity too. But, if you are resampling video frames, that suggests that you are resizing same sized frames to same output size. In that case, calculating contributor weights for each frame again is huge waste. Calculate that once, and then just reuse it.
  9. Dalija Prasnikar

    I will be less active for a few weeks

    Ouch.... I wish you full recovery.... I would also say speedy, but you don't recover fast from that thingy.... I also had mild symptoms (I had way worse flu infections), but fatigue is beyond extreme... I literally slept for a month. Absolutely. It is quite bad experience even with mild symptoms.
  10. Dalija Prasnikar

    caFree & ,Free??

    I suggest that you read once again what @Remy Lebeau posted. You example is horrible and no amount of dancing around it will ever make it work properly. When you run it, and it works... that will only be an illusion caused by undefined behavior and a touch of luck.
  11. Dalija Prasnikar

    caFree & ,Free??

    And that is exactly the situation OP has encountered here. I guess you missed that part.
  12. Dalija Prasnikar

    caFree & ,Free??

    No. It is not OK. You are trying to release the form twice. Once explicitly by calling Free and once by setting on close Action to caFree. This may work under some circumstances, like @balabuev mentioned caFree triggers posting CM_RELEASE message to the form window handle. If there is no code that will pump the message queue (like Application.ProcessMessages) between the time OnFormClose is called and your explicit call to Free, then calling Free will actually destroy the form and along with it its window handle and message posted to that handle will be discarded because window no longer exists. However, if CM_RELEASE message is processed and handled before your explicit Free call, form will already be destroyed at the point you call Free and hence the error you are seeing (presumably from EurekaLog) Because you have added some other code in between that is calling Application.ProcessMessages. You have to choose one option. Either you will use caFree or you will use Free. Using both and hoping for the best is not good option even if it works, because it can be easily broken, which you now have first hand experience. If you need to retrieve some value from the form after it is closed, then you shouldn't use caFree anyway because you may access dead form - again depending on the other surrounding code. Another reason to explicitly Free form is that this makes memory management more obvious. You create form, do something with it, and then you release it.
  13. Dalija Prasnikar

    caFree & ,Free??

    ShowModal is not supported on Android and it is not recommended on iOS, and if you trust documentations it should be safe to use on macOS. Issue is most likely caused by some other code, not your general form handling code that you have here. http://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.Forms.TCommonCustomForm.ShowModal Your form handling is mostly correct. I would remove SaveFormPos from finally block because if something goes wrong you most likely don't want to save your form position. Also, if SaveFormPos can raise an exception, you will leak the form because FreeAndNil will not be called in that case. Also I would put f.var assignment inside try... block, because if that assignment raises and exception you will also leak form. And since form variable f is local variable and it is going out of scope right after you are releasing it, there is very little point in calling FreeAndNil, simple f.Free is enough.
  14. Dalija Prasnikar

    Learning Delphi

    Generally, books are the best resource for learning any language. More experienced developers can usually get they way around new language faster, so official documentation might suffice. Anyway, Delphi Language Guide is always a good place to start http://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Language_Guide_Index
  15. CB can use most of the Delphi code, but not all.
  16. Dalija Prasnikar

    QueryPerformanceCounter precision

    Yeah... but making a wrapper around C++ lib....
  17. Dalija Prasnikar

    QueryPerformanceCounter precision

    It would probably be easier to write the whole thing from scratch in Delphi.
  18. Dalija Prasnikar

    Determining why Delphi App Hangs

    I meant wrong time. Let me explain. procedure TMainForm.OnTimer(Sender: TObject); begin ChangeFooBarForkState; end; procedure TMainForm.BtnClick1(Sender: TObject); begin DoFoo; DoBar; DoFork; end; procedure TMainForm.BtnClick2(Sender: TObject); begin DoFoo; Application.ProcessMessages; DoBar; Application.ProcessMessages; DoFork; end; Let's say that DoFoo, DoBar and DoFork depend on some state that is changed on timer with ChangeFooBarForkState and if you call DoFoo, DoBar and DoFork in sequence with different state you will get wrong result. In BtnClick1 without ProcessMessages, those procedures will run serially without interruption and with consistent state, because OnTimer event cannnot run in the middle, but in BtnClick2 timer can be triggered and can mess up that state. Now, this is a bit contrived example and you can say that you can fix such code to work properly with timer, but the point is that just like thread safety can sometimes be tricky because code may work properly most of the time, ProcessMessages can also be tricky to do right because you have to think about all the potential messages that can be processed and it can be easy to overlook some and you may have random bad behavior that is hard to reproduce. Now, this timer example is based on real life scenario someone had somewhere, where Application.ProcessMessages was the problem, I just don't remember where I read about it or what was exact code in question.
  19. Dalija Prasnikar

    Sdk version in AndroidManifest file and Rad Studio

    I currently have API 29, but I am testing Delphi Android applications only on Android 7.0 device. I am not actively developing on Android with Delphi. When I started Delphi for Android was not suitable for my use case and didn't have support for devices I needed, so I had to use Android Studio.
  20. Dalija Prasnikar

    Determining why Delphi App Hangs

    Modal dialog will prevent user triggering actions, but it will not prevent triggering timers (if you have one) from causing possible unintended actions running at wrong time.
  21. Dalija Prasnikar

    Sdk version in AndroidManifest file and Rad Studio

    Upgrading the SDK opens possibility for incompatibilities. Applications with lower SDK version run in compatibility mode on newer versions of the OS. When you increase SDK version you are basically saying this application supports all new OS APIs. If your application (that includes RTL and FXM) does not support all new APIs it can crash or malfunction. See: https://quality.embarcadero.com/browse/RSP-27218 This issue has been resolved in 10.4 Sydney and Android 11 is now officially supported by Delphi. I am not sure if there are any other issues.
  22. Dalija Prasnikar

    Determining why Delphi App Hangs

    When I said put your code in background thread, I didn't mean literally like run exactly the same code in background thread. But for any code that runs long, Application.ProcessMessages is always the wrong solution. It may be quick fix at some point, but it is still a wrong solution. First step in writing better code is acknowledging that Application.ProcessMessages is wrong solution. Then and only then one can start going in different direction and start learning and applying better solutions. It can be long process, depending on the existing code you (I don't literally mean you) already have. But the sooner you start, the less work you will have in the future when you start removing Application.ProcessMessages. If you never start doing that, sooner or later you will encounter code where Application.ProcessMessages will not work as intended and you will not be able to make UI fully responsive when using it. Learning how to use background threads at that point - when you cannot properly take time to experiment and learn will only make it harder. It depends, but certainly more often than with Application.ProcessMessages approach.
  23. Dalija Prasnikar

    Determining why Delphi App Hangs

    Yes, it does. Until some timer throws you a curved ball. Yes, it is possible to polish Application.ProcessMessages approach and solve reentrancy issues around it. That still makes it a poor solution because you still have other problems I mentioned before.
  24. Dalija Prasnikar

    Determining why Delphi App Hangs

    The code where you call Application.ProcessMessages procedure TMainForm.BtnClick1(Sender: TObject); begin DoFoo; DoBar; DoFork; end; procedure TMainForm.BtnClick2(Sender: TObject); begin DoFoo; Application.ProcessMessages; DoBar; Application.ProcessMessages; DoFork; end; procedure TMainForm.BtnClick3(Sender: TObject); begin TThread.CreateAnonymousThread( procedure begin DoFoo; DoBar; DoFork; end).Start; end; Problem with Application.ProcessMessages is that code that would execute in one block without interruptions, like in first example, can now be interrupted and some other code can start running in the middle of it. For instance you can click same button twice. Or you can close form and destroy it while other code is still running and using it. Now moving in background thread does not solve those issues, because you can still click the button twice and you can close the form while you running something in the background. But, there are few things to consider here. First, while code with ApplicationProcessMessages can be interrupted at any point, code in background thread will run serially, one line after the other, just like the code that does not call Application.ProcessMessages. It is far easier to follow the logic (and debug) such code. One of the arguments for Application.ProcessMessages was that it is easy to use, comparing to multithreading. That is true only on the surface, it seems easy and that is why we were all using it. So you have beginner developer writing all kind of poor code in event handlers and application becomes unresponsive, so he is advised to use ApplicationProcessMessages, and he sprinkles his code with those and application might work better (seemingly). In the reality, he learned nothing, his code is really bad, and sooner or later when some user clicks something unexpected everything will fall apart. When you have to move code to the background thread, you need to think more about it and you need to isolate it better. Mere process of isolating functionality will make that code better. Now, you can still have developer that will just move the whole thing to the background without doing any of that, but that code will not seemingly work (that rarely happens) and it will not work properly, which will hopefully trigger the developer to ask for help and learn how to do that properly. There is a difference. If the UI reacts slowly that means when you drag the window and it will not drag smoothly, when you click the button you may not get immediate response, so you will click it again. Background thread does not block the UI so it does not matter how long it takes to cancel the operation. You can write your code in such manner that when action is canceled, user can immediately continue doing something else. You don't have to move data between threads - data is not contained within threads (unless you specifically create thread local data), you just need to prevent multiple threads changing the same data simultaneously.
  25. Dalija Prasnikar

    Determining why Delphi App Hangs

    First, as we all know (I hope) if application cannot process messages, it becomes unresponsive and OS (and user) can kill it, because it may look like it is dead. Application.ProcessMessages pumps the message queue so the OS can see that application is still alive. There are few problems with that approach. Most obvious problem is that such code becomes re-entrant. That can cause some nasty side-effects depending on the code you are executing. But main issue is that you are still running slow operation in main thread, and no matter how much you are able to interrupt that execution with calls to Application.ProcessMessages, this will still slow down UI processing and application may respond to user input slowly. Also, this is not just the problem with reacting to input, but all the calls to Application.ProcessMessages will make that long operation running even longer. Next issue that is often overlooked is that some parts of the long running process may not always execute fast enough. Imagine connecting to some web service and retrieving some very small amount of data. In perfect conditions that may take blink of an eye, but if connection is bad for any reason, this operation can block the main thread for much longer. And Application.ProcessMessages will not help you with that. Also, for cross-platform development, this is more important because mobile devices will kill non responsive application much faster. On Android you cannot even freely perform network operations in the context of the main thread because OS will thow exception if you try. Also on android Application.ProcessMessages no longer works and can deadlock the application.
×