Avoid this mistake
Posted: Mon Feb 10, 2020 4:19 pm
Following the pattern my .dpr code looks like this:
It is easy to forget that whatever code you put in CreateGlobalCEFApp gets executed multiple times from multiple processes and that can cause unanticipated problems. I had code in my CreateGlobalCEFApp that effectively was doing something like this:
Looks harmless enough. BUT, consider that TRegIniFile.Create will attempt to create the key 'SOFTWARE\Appname' if it does not exist. And since this code will actually get executed multiple times in multiple processes on startup, two processes might be trying to do this at exactly the same time. The registry may be locked and you could get a registry exception on startup 'Unable to create key' because two processes are trying to create a registry key it simultaneously.
I had this code in program for quite a while until one day a user said, by the way I keep getting this error. Thousands of users never saw it or it happened so rarely they didn't bother to report it. But one user got it every time.
I had forgotten the way CEF initialization works and that this code gets executed multiple times near simultaneously. And, I had overlooked the fact that TRegIniFile.Create will create a key if one does not already exist, which is the case on the very first run of my app. Be careful what you put in your TCefApplication initialization code.
I decided to pass this along so you can avoid my mistake.
R Greg Dawson
Code: Select all
begin
CreateGlobalCEFApp;
if GlobalCEFApp.StartMainProcess then
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'AppName';
Application.CreateForm(TMainView, MainView);
Application.Run;
end;
DestroyGlobalCEFApp;
end.
Code: Select all
procedure CreateGlobalCEFApp;
var
RegIniFile: TRegIniFile;
DoClearCache: Boolean;
begin
RegIniFile := TRegIniFile.Create('SOFTWARE\AppName');
try
DoClearCache := RegIniFile.ReadBool('', 'ClearCache', False);
finally
RegIniFile.Free;
end;
GlobalCEFApp := TCefApplication.Create;
with GlobalCEFApp do
begin
CheckCEFFiles := False;
OnWebKitInitialized := GlobalCEFApp_OnWebKitInitialized;
Cache := CefCacheDir;
DeleteCache := DoClearCache;
DeleteCookies := False;
EnableHighDPISupport := True;
end;
end.
I had this code in program for quite a while until one day a user said, by the way I keep getting this error. Thousands of users never saw it or it happened so rarely they didn't bother to report it. But one user got it every time.
I had forgotten the way CEF initialization works and that this code gets executed multiple times near simultaneously. And, I had overlooked the fact that TRegIniFile.Create will create a key if one does not already exist, which is the case on the very first run of my app. Be careful what you put in your TCefApplication initialization code.
I decided to pass this along so you can avoid my mistake.
R Greg Dawson