Jump to content

Dalija Prasnikar

Members
  • Content Count

    1067
  • Joined

  • Last visited

  • Days Won

    91

Posts posted by Dalija Prasnikar


  1. 5 hours ago, Vincent Parrett said:

    I saw that, but I'm not using the built in Weak stuff - this is in XE7 Win32 before weak was available - I'm using my own weak reference library - it's not as convenient (need to use a base class) but has worked well for me for the last 12 years or so. I still take a hard reference from the weak and check that for nil rather than relying on the .IsAlive property when using it in threads.

    How much you pay me to prove your Weak library is not thread safe :classic_biggrin:

     

    Main problem with FreeAndNil supporters is that it is treated as silver bullet and it is not. Like @Stefan Glienke said, there are better tools for the job. And in multithreading scenario all bets are off. Of course, if you suspect something is out of order then you can add some help like calling FreeAndNil for debugging purposes. Been there, done that. But sprinkling them all over the code, just in case? Sorry, but that is hard no. It just pollutes the code and gives you false sense of security, because it will nil just one reference and all others will turn into dangling pointers.

     

    In other words, if FreeandNil can save me 70 hours of work in one case, it would still cost me way more work hours, when I have to read all code with FreeAndNil wondering whether there is a real purpose behind that call or it is there just for luck.


  2. 24 minutes ago, Der schöne Günther said:

    What did I miss? What I understand is that

    1. It is not part of the language, it is just a regular method from the standard library
    2. Earlier versions did have an untyped parameter and let you pass in things that were not descendants of TObject

    If that is all, how can you even have an opinion on that? What is there to talk about? Can somebody get me up to date with just one or two sentences?

     

    There is plenty to talk about. It is not just about FreeAndNil, but about constructing and destructing object and all the fine print around that process. While on the surface this topic seems simple enough and that there is nothing to talk about, it is rather complex topic and many developers, even experienced ones, easily forget about some very important facts around this topic that can cause serious issues in applications.

    • Like 3
    • Thanks 1

  3. 14 hours ago, ringli said:

    The whole thing is already running in a simple thread, but sometimes it seems to hang a bit. Therefore I wanted to test if there is a better or simpler solution. I always tend to solve everything too complicated. :classic_blink:

    If you are already running it in a thread, then adding event bus on its own will not solve your problem. 

     

    Even bus would help decoupling your code that is doing the search from the code that is showing the results, but it will not run faster. On the contrary. Since you are adding results to the UI, that part needs to run in the main thread. So you would use TThread.Queue or TThread.Synchronize. Event bus would call the same code in order to run event handler in the main thread. But when you do that you are calling it directly. Sending message through event bus runs a bit more code. You need to create message (event) which will cost some time, depending on the event type and the data it passes. Then sending message alone will lock the collection of subscribers, iterate through that collection, locate appropriate subscriber and then it will invoke event handler for that subscriber. And when iteration is completed it needs to unlock collection. 

     

    So decoupling comes at some price. In most cases that price is well worth paying, because bus overhead is very small comparing to other code that runs, but it will definitely not run faster than some code that is directly wired and invoked.

     

    Why is your code having problems, is hard to say without seeing the code. Also, when you are searching on disk, performance will be tied with the content of the disk, and its hardware characteristics, as well as the whole system. For instance, if you try to access physically damaged part of the disk OS call may hang on such spot for minutes. 


  4. 13 hours ago, ringli said:

    The project seems to be very interesting.

    Thanks!

    13 hours ago, ringli said:

    So far I have no experience with an event bus to be able to estimate whether I can use the library in my small hobby projects.

     

    For me (and I'm sure for others) a few small practical examples would be very instructive. It would be great if you could upload some examples to the github repository.

    I will try to add some. I will need some time to prepare some meaningful examples that can show potential use cases.

     

    Event bus is a messaging system. Delphi already has basic event bus implementation in System.Messaging https://docwiki.embarcadero.com/CodeExamples/Alexandria/en/System.Messaging_(Delphi) You can also look at the examples there as those use cases apply to my event bus, too.

     

    Main difference is that System.Messaging is not thread-safe and you can only use it to send messages in the context of the main thread. If you want to send messages across multiple threads you need a thread-safe event bus, like NX Horizon. Because, it is thread-safe, it also has some additional features like dispatching events (messages) asynchronously in the background thread.

     

    Maybe the easies way to explain what is event bus is comparing it to a Button OnClick event handler. When user clicks a button code in the OnClick event handler will run. main difference (besides multithreading support) is that with button and its event handler there is usually deeper connection and there is direct link with the button and its event handler. For instance if you click Help button on some form, you would want to open Help window from its OnClick event handler. But in that case your form with button needs to know about help form. If you have many forms that need to open help form will create tight coupling between all those forms and help form. 

     

    With event bus, you can declare TOpenHelp event type and then you can subscribe some code to such event type. In your forms with help buttons, you would still need OnClick event handler, but instead of directly opening help form from that OnClick event you can send a message to event bus that TOpenHelp event happened. And then subscribers to that event (there can be more than one) will receive it and run the appropriate code in associated subscription event handler. This way your forms don't need to know about your help form, and code handling your help form does not need to know from where TOpenHelp came from. 

     

    Event type also serves two purposes. Its type tells that particular event happened, and its content (event can be any automatically managed or value type) is used to pass additional data. for instance if the TOpenHelp is integer type, you use it to store and pass help page number depending on which help button is clicked and then you can open help on particular help page. 

     

    Another example would be downloading some files in the background thread and then sending TDownloadCompleted event from that thread with some data about particular download and then subscribers can handle and do whatever they need to do with that data. Process it further, show it to the user, or anything else. 

    • Like 2

  5. 32 minutes ago, Rollo62 said:

    Thanks for the nice and clean library, looks very good.

    Thanks!

    Quote

    What I'm missing still, same as in the DEB library, is the possibiltiy to easily subscribe and use anonymous methods instead of event methods.

    Why is that, and is there any plan to add such feature later on ?

    There are few reasons why they are not implemented as of now. 

     

    First, I wrote this for my own needs and in my code I used regular methods, so I didn't had immediate need for anonymous methods. Next, I wrote about this event bus in my recent book Delphi Thread Safety Pattern, so I wanted to keep code as minimal as possible and focused on bus itself.

     

    Anonymous methods are definitely one of the potential future enhancements, but I wanted to publish the code as soon as possible instead of waiting to polish it more as this might have postponed release indefinitely.

    • Like 1

  6.  I have published initial release of NX Horizon Event Bus for Delphi as Open Source on GitHub.

     

    Features:

    • implements the publish/subscribe pattern, decoupling publishers and subscribers
    • events are categorized by type
    • any Delphi type can be used as an event
    • supports four types of event delivery: synchronous, asynchronous, synchronous in the context of the main thread, and asynchronous in the context of the main thread
    • provides generic record and reference-counted class wrappers for easier usage and management of existing types as events
    • simple in both implementation and usage
    • fast
    • full thread safety


    https://github.com/dalijap/nx-horizon

    • Like 9
    • Thanks 7

  7. Hi,

     

    I have just released new book: Delphi Thread Safety Patterns. https://dalija.prasnikar.info/delphitspatt/

     

    It is on promotional sale until June,14. You can use Coupon Code: DTSPATT10 at checkout to get a $10 discount.

     

    At the moment there are two options: you can purchase eBook only or bundle: eBook and paper edition (those are separate purchases that go through different sellers and you will receive instructions for paper book with the eBook order).

     

    Paper book only on the Amazon is not available for the time being. 

     

    Thank you all for the support!

    • Like 15
    • Thanks 3

  8. 12 hours ago, ioan said:

    I'll try but I'm not sure if it makes any difference. The code in TThread.Create where the datamodule is created is executed in the main thread. 

    Are you sure it is executed in the context of the main thread? Because that is not what the stack trace says. It shows it is called from within TOutThread.Execute method.

     

    Anyway, whatever the problem is, there is not enough code to determine what is the root cause. Data modules can be constructed in the background threads, but only and only if all components used are thread safe in that regard. In other words if they support being constructed in background thread. How they are configured and what other components are linked as properties also impacts the thread safety.

     

    Additional comment. That application does not have memory leaks is good, but not having memory leaks does not mean that code is thread-safe and that it will run correctly.

    • Like 2

  9. 43 minutes ago, wuwuxin said:

    Thank you for the link.  On one hand, string is listed as a reserved work, on the other hand, it also says "System.String" is an alias for "UnicodeString".......... 

    Being reserved word only means that you cannot use those words as identifiers. It does not tell you anything what each reserved word represents in the language.

     

    If you are asking about coding style and why is string written in small caps, then being reserved word has a meaning in that context because there is a coding style rule (which you don't have to follow, of course) that says reserved words are written in small caps. 

     

    When you are talking about string being an alias for UnicodeString then this describes its semantic - its behavior and what it represents. "string" describes default string type and its definition can change in different compilers. 

    For instance, in Delphi 1 string was alias to ShortString, and in Delphi 2 - Delphi 2007 it was alias for AnsiString, and since Delphi 2009 string is alias for UnicodeString. 

    • Thanks 1

  10. 1 hour ago, wuwuxin said:

    This has been pestering me for a while

     

    For the string type,  should be it "String", or "string",  I saw the Delphi source code mixes the uses.  Some third-party code uses "String", while some uses "string".

    If you follow a guideline that all reserved words (keywords) are written in small caps, then string which is a keyword should be written as "string".

    • Like 2

  11. 1 hour ago, DelphiUdIT said:

    This is new to me ... a non-instantiated object that "executes" a method ....

    Executing method on nil reference is actually a language feature. But such method must be static and you must not access any instance fields if instance is nil. 

     

    One such method is TObject.Free that can be safely called on nil reference, because it checks whether object is nil before calling other code, in this case virtual destructor that cannot be executed on nil instance.

     

    procedure TObject.Free;
    begin
      if Self <> nil then
        Destroy;
    end;

    Additional explanation how static method dispatching works can be found here https://dalijap.blogspot.com/2021/07/virtual-methods-in-delphi.html

    • Like 2

  12. 1 hour ago, Uwe Raabe said:

    The background setting is theme agnostic. There are at least three Background_XXX entries in the Welcome Page subkey of the BDS\22.0 registry key.

     

    That is what I meant when I said all. We are on the same page here.

    1 hour ago, Uwe Raabe said:

    The problem with the settings dialog is that it only saves the changes for the selected (in that dialog) theme. Unsaved changes to previously selected themes are simply forgotten.

     

    There is a QP entry for that: Welcome Page background image does not always save changes

    That explains why I haven't bumped into that issue as I changed background settings for more than single theme, but I didn't do that all at once and changes were properly saved.


  13. 10 minutes ago, Rinzwind said:

    Was talking about the background dropdown (which contains mountain mist) at Tools -> Options -> Welcome Page . It doesn't preserve the chosen option.

    If by "option" you mean changing active theme an applying it in IDE, this is the wrong place. Dropdown with theme selection there will not change the theme, it is only a selector for setting background options for each available theme.


  14. 3 hours ago, Rinzwind said:

    That works. What does not work, is trying to change it to another theme like Mountain Mist. It is not saved. Also tried running as admin. Does this say something about their testing methods if something so obvious is missed?

    Where are you changing theme to Mountain Mist?

     

    Welcome page settings are meant to customize Welcome page settings for all themes, not for setting active theme. You can change active theme at User Interface -> Theme Manager page in Options.


  15. 3 hours ago, Joseph MItzen said:

    I'd be interested if anyone has any insight into why Delphi and FreePascal performed so poorly in this benchmark. I'd really like to rule out any mistakes on my end. If we can figure out what's killing the Delphi performance - and it's not me - these results should make for a very, very interesting QC feature request. :classic_biggrin:

     

    I don't know about FreePascal, but there are several things that have impact in Delphi compiler.

     

    First, being single pass compiler, possible compiler optimizations are more limited than in multiple pass compilers. Next, 64bit compiler in general has less optimizations than original Win32 compiler. I am not going into the why's because I don't have that information and everything would be pure speculation on my side. Also Delphi 64bit compiler is not optimally using all available CPU registers, so there will be more unnecessary memory operations.

     

    I know that having a compiler that can do more optimizations is beneficial, because you can focus on the code you write and not on how fast it will run, but whether we like it or not, when speed matters optimizing the algorithm has always been first step.

     

    For instance, this would be faster way to achieve same results:

     

    var
      total, num: Int64;
    begin
      total := 0;
      num := 3;
      while num <= 1000000000 do
        begin
          total := total + num;
          inc(num, 3);
        end;
    
      num := 5;
      while num <= 1000000000 do
        begin
          total := total + num;
          inc(num, 5);
        end;
    end;

    I know that this is not exactly the answer you are looking for.


  16. 6 minutes ago, corneliusdavid said:

    Strange that the numbering scheme is a little different than the 10.x series (e.g. 10.1 Berlin and 10.0 Seattle).

     

    People were confused by previous numbering scheme and plenty of people thought that 10.1, 10.2, 10.3 and 10.4 were just updates not major releases.

     

    So current numbering scheme for major releases is full number 11 vas major release and 11.1 is update (there were several patches, but they didn't have separate number) and next major release will be 12. Of course, it is possible that there will be other updates for version 11.


  17. 6 hours ago, CyberPeter said:

    It's an absolute disgrace.  They really don't care do they ?  Plenty of bugs reported already on this issue in https://quality.embarcadero.com (also by me).

    They tend to get closed as 'resolved' and duplicate.  Must be good for the stats.

    I don't know what's worse, not being able to fix something like this or totally ignoring the community and not communication about it at all.

    Issue needs to be reported only once. Adding duplicate reports does not help in solving issue faster.  When there is a duplicate report of any issue those are closed as duplicates to enable tracking status in one point not all over the place. This has nothing to do with statistics, this is basic QA workflow.

     

    It would be nice to have official statement, but there is not much anyone here can do about it.

    • Like 1
×