Jump to content

Dalija Prasnikar

Members
  • Content Count

    1148
  • Joined

  • Last visited

  • Days Won

    106

Everything posted by Dalija Prasnikar

  1. Yes, you are right. I am trying to solve one problem, while forgetting the broader picture. Although it might be easier to figure out what is wrong if the thread would just stall, comparing to having random issues somewhere else in the application.
  2. Those few cycles mean nothing comparing to constructing the whole component over and over again. So this kind of safeguard can be easily implemented without having any negative side effects. The property itself could be left as-is, but initial value can be set in constructor depending on the thread ID value: FMultiThreaded := TThread.CurrentThread.ThreadID <> MainThreadID;
  3. Well, that is rather unfortunate design choice as it can be easy for users of a library to overlook this requirement. Wouldn't it be better to autodetect whether component is created within background thread and set that property automatically rather than manually?
  4. Dalija Prasnikar

    Google Play requires Android 13 after 31. august !!!

    You can find more information in this thread
  5. Dalija Prasnikar

    Google Play requires Android 13 after 31. august !!!

    You need to recompile your application with the latest Delphi 11.3 and submit that to Play Store See: https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Supported_Target_Platforms#cite_note-11.3-1
  6. If the issue happens only when background thread is running, then background thread creates a problem. This sounds like memory issue, if FASTMM is not registering the leak, you are probably allocating and holding on to some memory that accumulates inside the thread. Another potential issue without a visible leak could be a memory fragmentation and then you have an issue when you try to allocate larger block of memory like bitmap.
  7. Yes. I started with explanation how to approach memory allocation issues (since you mentioned FASTMM), but I should have been more clear that this part is most likely not related to your current issue.
  8. It means that either code in the GUI or the code in thread is exhausting the memory. So you need to know which one causes the problem if you want to locate it. For start, just comment out all the code in thread and see how application behaves, then you can start turning on parts of the code in thread until you hit the issue. There is plenty of code we don't see here so it is hard to say what is the problem. Just because FASTMM does not show the leak that does not mean that there is no memory leak, it is just that it is not classical memory leak where you allocate memory and you don't release it. Another form of a leak is that you keep allocating memory and holding on to it even after you no longer need it. such memory will be properly released on application exit, but while running application can still exhaust all available memory. BTW, some of your code in thread is not properly handling allocations/deallocations. You have try...finally blocks that do more than they should, you don't protect all allocations with try block - the other option, would be to initialize all object instances to nil first, and you have unnecessary Assigned checks before calling Free which can safely run on nil object instances. All that tells me that your memory management code is not exactly stellar and that you probably similarly poor code in other parts of your application. So chances are rather high that your code somewhere in your application is causing you a trouble and that it has nothing to do with ICS alone. However, EOutOfResources error is not about a memory allocation but leaking GDI objects. Those leaks will not be reported by FASTMM. Because it is wrapped inside GDICheck it is possible that there is no leak at all, but some other GDI error.
  9. Dalija Prasnikar

    Where is the link to register to the forum?

    chatGPT I would like to see that one working... https://meta.stackexchange.com/a/391067/313443
  10. Dalija Prasnikar

    Where is the link to register to the forum?

    Stack Overflow has a good system with casting flags where certain amount of flags automatically deletes the post. Flags are available based on reputation to prevent abuse and bad flags cause flagging suspension. Also moderators can issue manual suspension. Because we are small forum, you could even manually give such delete flag capabilities to trusted users where you know they will not be abused and automatically delete posts even with single flag. There is enough of us to keep the site clean, the only thing needed is infrastructure that would allow that.
  11. Dalija Prasnikar

    Are local TGUIDS preinitialized?

    I will have to change my position. I was focused on behavior where compiler would catch all cases where record would be uninitialized - by all I don't mean having different code paths where compiler cannot easily determine whether something is initialized or not even for types it currently shows warnings. To catch all such cases, calling record method would also need to show a warning, but there is no way compiler can differentiate between method that initializes a record and method that expects already initialized method - the difference between imagined TGuid.Clear and TGUID.IsEmpty. However, for other value types calling a method does not trigger a warning and simply disables further warnings, so such behavior could be easily extended to non-managed fields in records without causing any bogus warnings and would not be any more difficult to achieve than existing warnings for other value types. It is likely that variant parts in records would have to be excluded as accessing and initializing one field does not mean that another field that shares same memory would be fully initialized (memory overlap can be only partial) and it is possible that tracking sizes and what is initialized and what not would be too much in such scenario. There is a value in showing at least some warnings comparing to none.
  12. Dalija Prasnikar

    Are local TGUIDS preinitialized?

    I think there was some article about C# covering similar area that explained the problems rather well. I cannot find it now.
  13. Dalija Prasnikar

    Are local TGUIDS preinitialized?

    It means that it can be hard to tell whether record is initialized or not. For instance you could have TGuid.Clear method that would initialize record, but there is not way to tell what that method does comparing to TGuid.IsEmpty or any other that would expect initialized record. It is not as much that warnings cannot be emitted, but that there would be a lot of bogus warnings in such case, which defeats the purpose of a warning.
  14. Dalija Prasnikar

    Are local TGUIDS preinitialized?

    From https://quality.embarcadero.com/browse/RSP-24383 Warning/Error on record fields used without initialization
  15. Dalija Prasnikar

    Are local TGUIDS preinitialized?

    TGUID is a regular record type, so it is not initialized. Only managed types are initialized, including custom managed records.
  16. If you have a loop you will have a capture problem, except in most trivial cases. It is not that hard to spot. The main problem is that plenty of people are completely unaware of the issue as they haven't used anonymous procedures much.
  17. Negotiations with Stack Exchange have been completed and strike has effectively ended. You can read more at https://meta.stackexchange.com/questions/391847/moderation-strike-results-of-negotiations There is also expected update to the strike letter. Even though there was a conclusion to the strike, there are different levels of satisfaction with what has been achieved and everyone is free to continue the participation or not as they wish. This is just the end of organized process . Also some things are still being worked on (establishing AI detection heuristics for moderation in particular) and there are newly announced features coming to Stack Overflow like Overflow AI https://stackoverflow.blog/2023/07/27/announcing-overflowai/ so there is still plenty of room for things to go awry. I wish to thank everyone who participated in the strike. Every signature meant a lot.
  18. Dalija Prasnikar

    Problem writing to memo on main form from thread

    TThread.Synchronize is blocking call and it will block until the code runs in the context of main thread. TThread.Queue adds that code in a queue and returns immediately and the code will run some time in the future. Besides those differences both procedures do the same thing, run the code in the context of main thread and are thread safe. Depending on which ones of those methods you call and in which order the output you will get can differ in order but will be deterministic in a way that you can know how that order will look like by reading the code. However, that exact order is only valid for single thread. When you have multiple threads running in the background (and with TParallel.For you will commonly have more than one) the order in which those multiple threads execute synchronized code can be interleaved and output from one thread can appear in between the output from another thread.
  19. Dalija Prasnikar

    Problem writing to memo on main form from thread

    You should remove Application.ProcessMessages from that code as it serves no purpose. TParallel.For is blocking call and that means it will block the thread from which it is called. When you call it from the context of the main thread it will block the main thread. TThread.Synchronize and TThread.Queue procedure can only work in coordination with main thread which periodically calls (this is a bit simplified explanation) CheckSynchronize procedure that will run any pending code that requires synchronization. If the main thread is blocked - not executing any code as it is waiting for TParallel.for to finish it cannot run CheckSynchronize and it will deadlock if you use TThread.Synchronize in any code that is called inside TParallel.For because Synchronize itself is also blocking call. TThread.Queue is not blocking and code will not deadlock, but it is still not a solution because all code inside will run after TParellel.For completes. Additionally, TParallel.For will cause your application to be unresponsive for the whole time it is running, and because of that it should never be called from the main thread. If you need to parallelize some task, run additional thread that will call TParralel.For and you will be able to use either Synchronize or Queue again, and your UI will not be blocked while you are running your parallel task.
  20. Because there are differences between different operating systems and how their internals work. In other words, some things and some workflows that are possible on one operating system is impossible on another. Like I said before ExecuteWork is internal method and MUST NOT be used. It is part of the interface so internal code can call that method when appropriate, but this method is not part of public API. Forget that it exists. Just because some method is available and can be called does not mean it is meant to be used by developers, regardless of how it is available - through interface or directly through object instance. Another example of methods that should not be called directly is TThread.Execute, or TObject.FreeInstance... there are plenty of such examples around.
  21. Yes, it is impossible. Also this approach while works on Windows is also not the best one. The only way to wait is using fTask.Wait, but then the main thread will block and OS will kill your application. If you need to run some code after task completes the only way to do that is from within task procedure. Also if you start a task and then call wait you are defeating the purpose of having background thread in the first place. begin _Taskcomplete := false; fTask := TTask.Create( procedure begin // Here you do your task code while not _Taskcomplete do Lbl_Task.Text := ElapsedSec.ToString; TThread.Synchronize(nil, procedure begin // Here you can call code that needs to run after task is finished Lbl_Task.Text := 'task complete ..'; showMessage('we wait until Task Complete to show you this message !!'); end); end); fTask.Start; end;
  22. Additional update: The company is starting a new site covering AI prompt design https://meta.stackexchange.com/questions/390463/starting-the-prompt-design-site-a-new-home-in-our-stack-exchange-neighborhood and Stack Overflow CEO will have a keynote at WeAreDevelopers World Congress, along with workshops presenting "bright" future of Stack Exchange Network and GenAI https://www.linkedin.com/posts/stack-overflow_we-are-one-month-away-from-wearedevelopers-activity-7079488260372058113-eOPJ/ Currently negotiation is progressing rather slowly when it comes to AI moderation policy and reading between the lines it is quite possible that it will be dragged on until the conference. What will happen after that is hard to predict.
  23. There is no safe way to block main thread. You should never, ever block main thread, especially not on mobile devices that have slightly different workflow than Windows. And yes, don't use Sleep either. The only proper solution for your problem is not to wait, reorganize code, so you don't have to wait. Disable the UI to prevent user from starting something else while your task is running and enable the UI and run other code from within task procedure (synchronized) when the task is done. This is not a safe way. Your code is bad even on Windows, even though it seems like it works. This is the wrong way to deal with threads anywhere. Again, it is not about Delphi, it is that this is the wrong way to use threads.
  24. This is why you are failing. The main thread should not wait for background thread to finish. If you need to run something after your task is completed you need to change your code logic and initiate that code from within TTask procedure. If you wait you will block the main thread and this is not something you should be doing, unless it is some very brief period for some cleanup (even then you need to be careful) This is how you should use TTask to run task in background and then run some code after task finishes: begin fTask := TTask.Create( procedure begin // Here you do your task code ... TThread.Synchronize(nil, procedure begin // Here you can call code that needs to run after task is finished ... end); end); fTask.Start; end; If you change your code workflow, you will not need the Sleep or anything else. There is no magic there. Just because at some point it may look like it is doing what you want it to do, does not mean it is right way to do it.
  25. Do not call Application.ProcessMessages, it is a wrong solution to whatever problem you have.
×