Jump to content

Dalija Prasnikar

Members
  • Content Count

    1148
  • Joined

  • Last visited

  • Days Won

    106

Everything posted by Dalija Prasnikar

  1. Dalija Prasnikar

    Android does not start

    Again, if application crashes inside Java wrapper side, then you cannot debug it with Delphi. You need to see what is exact error message and then Google what feature is this error connected to. Then look at changed requirements in the official Android documentation and make appropriate changes. Because native Java applications also suffer from same issues when upgrading, usually you can find plenty of resources which will give you answer about precise configurations needed even without going through official documentation. Creating new Delphi application and then including those problematic features can also help to pinpoint exact problem. Most likely there is some configuration problem in your application manifest. But there could be other issues, like wrong JAR libraries and similar. Once you get new Delphi application up and running, you can see the differences in configuration and apply necessary changes to the old one.
  2. Dalija Prasnikar

    Android does not start

    Android development is very different from Windows development. Most likely cause of problems are changes and requirements for newer Android OS that were introduced in the meantime. It has nothing to do with compiler nor Delphi language. Google releases new Android version every year and to comply with those new OS releases and ability to upload applications on Play Store, Delphi Android applications need to support new OS and new Android SDK. There have been numerous changes between 10.2.3 and D11.3 considering Android development and your old application most likely uses features that were subject to change and that require additional or changed configurations or code. Without knowing which features you are using, it is impossible to say what needs to be changed. You can find list of changes and new requirements between releases in official Android documentation https://developer.android.com/tools/releases/platforms Also Delphi Android application runs inside a wrapper and if application crashes due to misconfiguration inside that wrapper, it will crash before any Delphi code starts running. That is why you cannot debug it. To understand what is happening and why it crashed you need to look at native Android error logs - logcat.
  3. Dalija Prasnikar

    Problems with Delphi class structure / visibility

    Without seeing where LemGame is declared and how it is impossible to say why you have an error. It is also important to note that sometimes you may get error in the IDE (read squiggly lines) in some perfectly valid code. You should always try to compile code to see real errors. also, when you do get compiler error, you should fix them in order they appear as the first error can cause subsequent issues for the compiler and it is possible that compiler will show more errors in otherwise valid code. But, it seems like your main problem is not with Delphi but with OOP principles in general as you are trying to access properties in a class without creating instance of a class. Class is just a template from which object instances are created. Before you create object instance data (class fields and properties) don't exist in memory, so there is nothing you can access there. The exception to that are class fields, properties and methods that are additionally marked with class descriptor. Those can be accessed directly. They are basically global variables that are organized under class namespace. See https://docwiki.embarcadero.com/RADStudio/Sydney/en/Properties_(Delphi)#Class_Properties Purpose behind creating object instances from class before using them is that most of the time you will need more than one. For instance, you can have one global object instance of a game, but you will need more instances of game characters or other game objects. Think of it, class gives you description about attributes and functionality of a person, and when you construct object instances of that class you will get separate persons: Joe, Mike, Alice... I would advise you to read a bit about Delphi language and some basic concepts. good place to start is https://learndelphi.org/ and Delphi Language Guide https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Language_Reference
  4. Dalija Prasnikar

    Loop a Delay in a thread??

    Counting is hard
  5. Dalija Prasnikar

    Loop a Delay in a thread??

    If you need to loop some code x times and break out on some condition, then the simplest logic would be: for i := 0 to x do begin if TEDBEngineSessionManager(DBSWhoIsOn.Handle).TryLock(1) then begin ... // if succesfull break out of the loop Break; end else TThread.Sleep(500); end;
  6. Dalija Prasnikar

    How can I allocate memory without raising exceptions ?

    Possible solutions in your scenario depends on what kind of string are you sending. Is it a predefined constant, or it is provided by the code in a thread, do you already have it in a string variable and just need a copy for posting., how large are those strings, is the data in string critical or is it just some discardable notification, what is your logic if there is not enough memory... Thanks for the compliments.
  7. Dalija Prasnikar

    How can I allocate memory without raising exceptions ?

    What exactly are you trying to do? This sounds like XY problem. See https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem Out of memory exception is recoverable if your application logic allows that at the moment it happens. For instance if there is enough free memory to do regular work, but there is not enough to load and process some large file user tries to open. This is why exception handlers are here for. So if you can logically recover from failing to allocate large string, you can just do the same using exception handlers. There will be no memory corruption when string allocation fails that will have negative effect on your application. While exception handling does have some small impact on performance, I seriously doubt that this will be your main problem comparing to all you would have to do to get even close to functionality you want to achieve. Delphi applications are full of exception handling (both direct and indirect) on all levels and applications are still running fast. For instance, merely declaring a string variable will insert hidden exception handling code around that string.
  8. Stack Overflow annual survey is live. You can find more info at https://meta.stackoverflow.com/questions/424565/complete-the-2023-developer-survey
  9. Dalija Prasnikar

    Stack Overflow Developer Survey for 2023

    I noticed the grin... but there are plenty of people that don't know how Meta voting works, so I explained just in case, for anyone reading this.
  10. Dalija Prasnikar

    Stack Overflow Developer Survey for 2023

    Meta rules are different. Voting usually means disagreement, not that the post is close worthy. Also this is official post and they have different weight even when unpopular.
  11. Dalija Prasnikar

    TParallel Version and TTask Version

    Yes, because interlocked operation are expensive. Multithreading always comes at a price. The code is more complicated, you need to pay attention to thread safety and it will generally run slower than single threaded code. Not every operation is worth doing in parallel. If some calculation takes longer time, you can run it in single background thread, so you can keep your application responsive, but for splitting some task to multiple threads, you need to make sure that the task can be successfully parallelized and that performance gained is significant enough. For any operation that runs less than a second, it is usually not even worth to start a single background thread, let alone starting multiple ones.
  12. Dalija Prasnikar

    TParallel Version and TTask Version

    Those two methods you have don't do the same thing. If you take a look to the result of the calculation, you will see that results are different. First method will increment sum 1000000 times and second will increment temporary value 1000000 times and then add that temporary result to the total sum 1000 times. So the second method runs more operations and that is why it runs slower. If you correct the code to calculate exactly the same sum in the second method, you will see that this one will run faster. for ThreadedI := 0 to Pred(1000) do begin Inc(ISum); end; Number of tasks running in both cases will be the same, but the second method has the advantage because the temporary calculation is not using interlocked operation which is costly, and only uses it to add that temporary sum to the final result. Overall, Parallel.For code will run interlocked operation 1000000 times, and task based method only 1000 times.
  13. Dalija Prasnikar

    About Delphi 11.3 CE Platform Selection

    Linux is only supported in Enterprise or higher SKU. Not even Professional SKU has Linux support. https://www.embarcadero.com/products/delphi/product-editions
  14. Dalija Prasnikar

    Why does a stack overflow cause a VCL application to terminate?

    Now we are going into territory I don't know well. When guard pages are used, recovering from stack overflow exception requires some "manual" handling. While I don't know what Delphi actually does when it happens, it is fairly obvious that stack overflow exception corrupts memory as applications die almost immediately afterwards due to random AV exceptions or just get killed by the OS.
  15. Dalija Prasnikar

    What is the meaning of 2 In here

    2 is Stride parameter. However, it does not actually do what people think it does. It divides work in chunks that will run on same task effectively limiting number of threads used for running parallel for loop at a time. Default value of stride is 1 which means that each pass will run independently of others. If the stride is 2, then Max number will be divided with 2 and there will be Max/2 number of chunks - tasks. If the Stride is same as Max then all passes will run inside single task. Someone writing this code though that stride defines index increments, but that is not so. Procedure will still run for each index from lower bound to upper bound regardless of stride value and calculation of prime numbers will be run for index 1, 2, 3,...
  16. Dalija Prasnikar

    Why does a stack overflow cause a VCL application to terminate?

    As the name says, stack overflow overflows the memory buffer reserved for stack. In other words, it writes data in memory that does not belong to the particular stack buffer. This can corrupt parts of memory used for something else and this is also why stack overflow exception is not recoverable and can crash the application.
  17. Dalija Prasnikar

    Creating multiple threads in a DLL

    Your thread class Execute method is basically empty. Is there any other code in there you didn't show? If not then that is the reason your code is running sequentially, as threads don't do anything. Also using lower priority for threads can make threads wait longer to get the CPU slice.
  18. Dalija Prasnikar

    How many people use Delphi?

    There are always other requirements besides speed. If the vendor requires support for many platforms then Electron is one of the available options that fits. Other requirements may be based on developers they have and their skillsets, as well as application features and target audience. For instance VSCode being written in Electron is foundation of their thriving plugin system not only because underlying technology is very suitable for that, but also because there is vast number of developers that can write those plugins.
  19. Dalija Prasnikar

    How many people use Delphi?

    Are you sure that poor speed is acceptable on desktop applications? What about applications that need to load complex forms where opening such form can take half a minute or more? Or when you need to create plenty of business objects, or when you need to do some textual processing. Good compiler means a lot in such cases. In last few Delphi releases @Stefan Glienke has continuously submitted hand crafted code to improve speed of some widely used RTL routines that have impact on overall performance. With better compiler that would not be necessary. Not only that, but with better compiler all other code we write would be faster and when speed matters we wouldn't have to bend over backwards, writing horribly unreadable code just to get the speed we need. We could just write the clean and readable and maintainable code and leave the dirty work to the compiler. Speed always matters. Now, Delphi still might be fast enough for many purposes, but for many that is simply not enough. Once it was state of the art compiler, now it is seriously falling behind.
  20. Dalija Prasnikar

    Using TIdHTTP in a thread

    I am sorry, but snippets of code where it is not clear what happens at which point and how everything is created and called are also not enough to figure out what exactly is wrong with your code. One of the things does sound suspicious: you say the thread is stuck in the limbo when timeout occurs and you have Sleep call which will cause thread to sleep if it is not terminated, Maybe there is a problem?
  21. Dalija Prasnikar

    Using TIdHTTP in a thread

    It is impossible to say what is going on without seeing your code.
  22. Dalija Prasnikar

    Stop/Abort Form creation..

    Your code logic sounds backward. You should run code in FormCreate inside the calling form and then depending on the result create TChangesLogForm or not. Or if the code really belongs to TChangesLogForm, you should not run that code within FormCreate, but after the form is shown (along with some indication that there is a work in progress) and then if there is an error retrieving the data, you can show error message and close the form in that moment.
  23. Following code would do the job procedure TUExtractForm.LoadURLAsyncPOST(const AURL, AText: string); const CONST_TIMEOUT = 1000; begin TTask.Run( procedure var HttpClient: TNetHTTPClient; HTTPRequest: TNetHTTPRequest; ParamsStream: TBytesStream; begin ParamsStream := nil; try HttpClient := TNetHTTPClient.Create(nil); try HttpClient.ConnectionTimeout := CONST_TIMEOUT; // Timeout HttpClient.ResponseTimeout := CONST_TIMEOUT; // Timeout HTTPRequest := TNetHTTPRequest.Create(HttpClient); HTTPRequest.Client := HttpClient; HTTPRequest.OnRequestCompleted := HTTPRequestCompleted; HTTPRequest.OnRequestError := HTTPRequestError; HTTPRequest.CustomHeaders['Content-Type'] := 'application/x-www-form-urlencoded'; ParamsStream := TBytesStream.Create(TEncoding.UTF8.GetBytes('input=' + TNetEncoding.URL.Encode(AText))); HTTPRequest.Post(AURL, ParamsStream); finally HttpClient.Free; ParamsStream.Free; end; except on E: Exception do begin TThread.Queue(nil, procedure begin ShowMessageFmt('Error: %s', [E.Message]); end); end; end; end); end; procedure TUExtractForm.HTTPRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse); var Content: string; begin if AResponse.StatusCode = 200 then begin Content := AResponse.ContentAsString; // replace #$A with new line Content := StringReplace(Content, #$A, sLineBreak, [rfReplaceAll]); URLMemo.Text := Content; end; end; procedure TUExtractForm.HTTPRequestError(const Sender: TObject; const AError: string); begin ShowMessageFmt('Error: %s', [AError]); end; However, your timeout setting is very low - one second, and this can cause issues if the server does not respond timely. I would just use default settings.
  24. TTask.Run already runs in background thread and that thread will not finish before HTTP client completes its work or times out. You don't need to run another thread inside task and you don't need to run a loop simulating timeout.
  25. I am not sure about that. THTTPClient has built in support for timeout. What are you trying to accomplish with your timeout implementation? Your code is needlessly complicated.
×