delphi,asynchronous,delphi-xe4,delphi-xe8,tadoquery , Asynchronous TADOQuery's OnFetchComplete not synchonized to main thread

Asynchronous TADOQuery's OnFetchComplete not synchonized to main thread


Tag: delphi,asynchronous,delphi-xe4,delphi-xe8,tadoquery

When using TADOQuery with [eoAsyncFetchNonBlocking] and attaching to OnFetchComplete event I found that OnFetchComplete is not executing in the main thread (tested in XE4 and XE8). I assume this a bug*, since most of us will do work in the UI on these type of event. I believe this to be the source of some problems in a larger project and I need a workaround.

[EDIT] *After reading the ADO documentation I know concede that this may not be a bug, but the multithreading problem remains.

Is there an elegant way to force to have code in this handler to execute on the main thread? I don't want to use a timer (but if that's the only solution I'll take it). Alternatively, is there an ADO Synchronization object I can wait for here or some other form of signaling to the ADO provider?

Here is a simplified sample that shows that the problem. My project is more complex with a factory creating and filling these datasets, but it would be analogous here to attaching the dataset to a grid inside ADOQuery1FetchComplete.

unit Unit4;


  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Data.Win.ADODB, Vcl.StdCtrls;

  TForm4 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ADOQuery1: TADOQuery;
    ADOConnection1: TADOConnection;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ADOQuery1FetchComplete(DataSet: TCustomADODataSet;
      const Error: Error; var EventStatus: TEventStatus);
    procedure FormCreate(Sender: TObject);
    { Private declarations }
    FMainThreadID : DWORD;
    { Public declarations }

  Form4: TForm4;


{$R *.dfm}

procedure TForm4.ADOQuery1FetchComplete(DataSet: TCustomADODataSet;
  const Error: Error; var EventStatus: TEventStatus);
  Assert(FMainThreadID = GetCurrentThreadId); //this assertion fails!
  // I need UI code here to run  FMainThreadID

procedure TForm4.Button1Click(Sender: TObject);

procedure TForm4.FormCreate(Sender: TObject);
    FMainThreadID := GetCurrentThreadId;


And the dfm simply has the query set with ExecuteOptions = [eoAsyncFetchNonBlocking] and OnFetchComplete handled.

object Form4: TForm4
  Left = 0
  Top = 0
  Caption = 'Form4'
  ClientHeight = 186
  ClientWidth = 258
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 24
    Top = 88
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  object ADOQuery1: TADOQuery
    Connection = ADOConnection1
    ExecuteOptions = [eoAsyncFetchNonBlocking]
    OnFetchComplete = ADOQuery1FetchComplete
    Parameters = <>
    SQL.Strings = (
    Left = 144
    Top = 16
  object ADOConnection1: TADOConnection
    Connected = True
    ConnectionString = 
      'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In' +
      'fo=False;Initial Catalog=DBNAME;Data Source=.\INSTANCENAME'
    LoginPrompt = False
    Provider = 'SQLOLEDB.1'
    Left = 40
    Top = 16

[EDIT] A suggestion was made to use TThread.Sychronize, but this is not a Delphi Thread.

If the GetCurrentThreadId is not sufficient evidence that the handler is called from another thread here are the callstacks of the main and problematic thread (I added a sleep in the main thread for good measure)

Main thread sleeping

:77d0c7bc ntdll.ZwDelayExecution + 0xc
:7745104f KERNELBASE.Sleep + 0xf
Vcl.Controls.TControl.WndProc((48401, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((48401, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
Vcl.StdCtrls.TButtonControl.WndProc((48401, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
Vcl.Controls.DoControlMsg(???,(no value))
Vcl.Controls.TWinControl.WMCommand((273, (), 1344, 0, (), 7275840, 0))
Vcl.Forms.TCustomForm.WMCommand((273, (), 1344, 0, (), 7275840, 0))
Vcl.Controls.TControl.WndProc((273, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((273, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
Vcl.Forms.TCustomForm.WndProc((273, 1344, 7275840, 0, 1344, 0, (), 1344, 111, (), 0, 0, ()))
:759b8e71 user32.CallNextHookEx + 0xb1
:759b90d1 ; C:\windows\SysWOW64\user32.dll
:759b932c ; C:\windows\SysWOW64\user32.dll
:759b9529 ; C:\windows\SysWOW64\user32.dll
:77d107d6 ntdll.KiUserCallbackDispatcher + 0x36
:759be4a9 ; C:\windows\SysWOW64\user32.dll
:711f19e4 ; C:\windows\WinSxS\\comctl32.dll
:711f1a7b ; C:\windows\WinSxS\\comctl32.dll
:759b8e71 user32.CallNextHookEx + 0xb1
:759b90d1 ; C:\windows\SysWOW64\user32.dll
:759bddd5 user32.CallWindowProcW + 0x95
:00532947 TWinControl.DefaultHandler + $EB
:00532836 TWinControl.WndProc + $5CA
:00544cdd TButtonControl.WndProc + $71
:004c9162 StdWndProc + $16
:759b8e71 user32.CallNextHookEx + 0xb1
:759b90d1 ; C:\windows\SysWOW64\user32.dll
:759ba66f ; C:\windows\SysWOW64\user32.dll
:759ba6e0 user32.DispatchMessageW + 0x10
:005bb158 TApplication.ProcessMessage + $F8

Other thread calling the handler

Data.Win.ADODB.TCustomADODataSet.FetchComplete(nil,89849068,Pointer($3299D8) as _Recordset)
:6b7ab81d ; C:\Program Files (x86)\Common Files\System\ado\msado15.dll
:6b7ab4b6 ; C:\Program Files (x86)\Common Files\System\ado\msado15.dll
:6b7a17c8 ; C:\Program Files (x86)\Common Files\System\ado\msado15.dll
:6b7b616f ; C:\Program Files (x86)\Common Files\System\ado\msado15.dll
:69038991 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:69038bd6 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:69038d54 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:69037a02 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:69021205 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:69038034 ; C:\Program Files (x86)\Common Files\System\msadc\msadce.dll
:77a07c04 KERNEL32.BaseThreadInitThunk + 0x24
:77d2ad1f ntdll.RtlInitializeExceptionChain + 0x8f
:77d2acea ntdll.RtlInitializeExceptionChain + 0x5a


In my experience the easier way is to use either:

Synchronize or TThread.Queue

This is not a bug or at least not a VCL bug. This behavior is handled by the provider and we cannot say it is not following the specification because there is no specification about how to manage the asynchrony of those events. All the spec says is the following:


Indicates that the main thread never blocks while retrieving. If the requested row has not been retrieved, the current row automatically moves to the end of the file.

This is an example of code warning the main thread that the execution is completed:

procedure TForm1.ADOQuery1FetchComplete(DataSet: TCustomADODataSet;
  const Error: Error; var EventStatus: TEventStatus);
      ShowMessage('FetchData Completed');


I confirmed this. It will work for versions 6, 7, XE4 and XE7 (I don't have other version here). There is nothing wrong with using Synchronize to inject your code in order to execute into the main thread context. Also, I want to get your attention to the fact that DataSet is merely a pointer (actually a reference) to your ADOQuery Object, so you don't necessarily have to reference it on your anonymous method, this is an important fact for older versions like 6 or 7, because anonymous methods does not exists.



Calling a function from outside of require which is written inside of require in dojo

<html> <head> <script> require(["dojo/ready"],function(ready){ function init(dataItem) { alert("inside init method") updateData(dataItem); } function updateData(dataItem){ //inside this function, i am creating some breadcrumb and making each part of it a link. //Now that link is calling another method outerFunction() } ready(function(){ init({ type: "All Locations", id: "All_Locations" }); }); }); function...

Custom component controls keep re-creating

I'm a newbie in Firemonkey/custom controls so sorry if this is a banal question or a duplicate one but I'm stuck and can't figure it out. Here's the code of my custom control unit swScheduler; interface uses System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.StdCtrls, FMX.Calendar, FMX.Objects; type TswScheduler = class(TControl) private {...

Firemonkey ListView item indexes not updating

I'm using a TListView in Firemonkey. On startup, I create 3 list view headers and keep references to them for future use (specifically inserting items below each header). FItemHeader:= LV.Items.Add; FItemHeader.Purpose:= TListItemPurpose.Header; FItemHeader.Text:= 'Items'; FChargeHeader:= LV.Items.Add; FChargeHeader.Purpose:= TListItemPurpose.Header; FChargeHeader.Text:= 'Charges'; FPaymentHeader:= LV.Items.Add; FPaymentHeader.Purpose:= TListItemPurpose.Header; FPaymentHeader.Text:= 'Payments'; Then, I've added a...

async await for a HttpClient.PostAsync call

I'm trying to wrap a call to PostAsync so I don't have to recode the call sequence all over my code base. The issue I'm having is the HttpResponseMessage I assigned from the call is not the same as the one the consumer of my method calls. Here is the...

How should I execute functions only one after another in JavaScript?

I am trying to make a time conversion tool, first thing it does is gets the co-ordinates of both the cities you enter and then calculates time accordingly. But the problem I am facing is that the function which gets the co-ordinates takes some time and it is asynchronous as...

Why is the task is not cancelled when I call CancellationTokenSource's Cancel method in async method?

I created a small wrapper around CancellationToken and CancellationTokenSource. The problem I have is that the CancelAsync method of CancellationHelper doesn't work as expected. I'm experiencing the problem with the ItShouldThrowAExceptionButStallsInstead method. To cancel the running task, it calls await coordinator.CancelAsync();, but the task is not cancelled actually and doesn't...

SetProcessWorkingSetSize does not work in compiling 64bit

I use the following command to reduce the memory usage of my program, I'm actually testing it, only when I compile the program in 64bit this command does not work fot, no error occurs, only the memory in task managerIt does not decrease too, since in compiling 32bit works perfectly,...

How to call the original class's code when a class helper is in scope?

I'm doing some unit testing on an improved version of quicksort. The (hopefully) faster version is implemented using: TArrayHelper = class helper for System.Generics.Collections.TArray .... class procedure Sort<T>(var Values: array of T); overload; static; class procedure Sort<T>(var Values: array of T; Comparer: IComparer<T>); overload; static; .... I know for now...

Component event detection in Delphi

I am developing a DataAware component and executing some code after the database is open. This is the code I have at the moment: TMyDataAwareComponent = class(TDataAwareComponent) private { Private declarations } procedure ToBeExecutedOnAfterOpen(DataSet: TDataSet); protected { Protected declarations } public { Public declarations } constructor Create(AOwner: TComponent); override; end;...

Async await usage for MongoDB repository

I have a MongoDB repository class as you see below: public class MongoDbRepository<TEntity> : IRepository<TEntity> where TEntity : EntityBase { private IMongoClient client; private IMongoDatabase database; private IMongoCollection<TEntity> collection; public MongoDbRepository() { client = new MongoClient(); database = client.GetDatabase("Test"); collection = database.GetCollection<TEntity>(typeof(TEntity).Name); } public async Task Insert(TEntity entity) { if...

How to use the Akka ask pattern without blocking

Hi I have a actor which is responsible for fetching data from a database, turning it into a list and sending it back to the sender. I am using the ask pattern to receive response from my actor, because I don't want to use await.result because this approach will block...

ElasticSearch asynchronous post

I'm posting data on my ElasticSearch database. I've noticed that data is not immediately available, it requires some milliseconds to show up in a GET request. I can live with that (after all, the calls are asynchronous so this behavior is expected) but in my test code I need to...

PasswordChar in Delphi XE8's TMemo

I spent a few hours searching Google to see if anyone had shared their articles, but came up empty-handed. If it's possible, I want to know how to enable/disable the passwordChar in Delphi XE8's TMemo to hide user input like in TEdit. ? Maybe via a checkbox! So when the...

See when Delphi Twebbrowser starts loading a page

I am using delphi's TWebbrowser to navigate to a php file I created. I have a loading screen I would like to show when the page is loading or processing commands. How can I detect when it is being refreshed or still loading. currently I am using the ondocumentcomplete to...

Dynamically build table after it recieves information from service

HTML Code: <table class="table table-bordered table-striped"> <thead> <tr> <td>one</td> <td>two</td> <td>three</td> </tr> </thead> <tbody> <tr ng-repeat="color in colors"> <td>{{ }}</td> <td>{{ color.two }}</td> <td>{{ color.three }}</td> </tr> </tbody> </table> Controller: var SomeController = function ($scope, SomeService, $window) { var colors= []; SomeService.someFunction().success(function...

Reduce lines, use case?

How to reduce the lines, I could use case? I feel that this code is too large, no way to improve? if valmes.Text = '01' then WebTesta.OleObject.Document.all.Item('expmonth', 0).value := '0'; if valmes.Text = '02' then WebTesta.OleObject.Document.all.Item('expmonth', 0).value := '1'; if valmes.Text = '03' then WebTesta.OleObject.Document.all.Item('expmonth', 0).value := '2'; if valmes.Text...

Does Ruby support nonblocking HTTP requests without a third-party library?

I am writing an API to access resources on one of my servers. Part of this API will make HTTP requests. In the name of good software design, I don't want my API to be blocking. I am fairly new to Ruby, but in Java I would provide an Asynchronous...

Delphi generic frame

I'm still here with a questione about Delphi frames. I would like to create an application that use various type of frames in order to manage different database tables, so trying to understand how to do this kind of task I've create a simple Delphi Form: unit main; interface uses...

Set node state in a virtual tree

I have created a virtual tree with multiple node and I want to disable some of them. I've seen there's a States property of a node. Which is a property of a type TVirtualNodeStates so I've check what kind of states I can set and apparently TVirtualNodeStates is a set...

Call method after asynchronous request obj-c

In my app I init a new object, where there is method which calls NSURLConnection's sendAsynchronousRequest method. After the request, I would like to call a method in the caller UIViewController. I tried to use a static method but I then I can't control IBOutlets. How can I do this?...

Missing operator or semicolon in Delphi 7

I've got the error message "Missing operator or semicolon" on line 38 of this code: procedure TForm1.SpinEdit1Change(Sender: TObject); begin case SpinEdit1.Value of 1: Label6.Caption('rok'); // line 38 end; end; end. Does somebody know what I am missing? Thank you....

Contexts and callbacks from asynchronous tasks

I've been experiencing this problem on some devices, especially Samsung. I have an activity that has 7 fragments. In most of them, I start an async task for getting some data. I handle the exceptions by creating a handler in onCreateView(). handler = new Handler(new Handler.Callback() { @Override public boolean...

Does “enable runtime themes” affect performance?

I've recently changed "enable runtime themes" value in the project options and I'm wondering if it's value affects application's performances and, in case, in which manner? Hope someone can clarify me this point.

Exception in async task gets intercepted in Visual Studio

I want to run several tasks, some of which would complete async'ly, and then wait for all of them to complete. As the tasks may throw exceptions, I want to catch and log them. sample code for that: static async Task doit(int x) { try { Console.WriteLine("{0} {1} start", x,...

How to create a Task from already asynchronous code?

I have some code that's already asynchronous - just not using the Task system. I would like to make it a lightweight Task, if possible, so that code may leverage it as a Task. So I want to take this: void BeginThing(Action callback); And turn it into this pseudocode: Task...

How to convert this JSON to a datatable?

[ [ "<div id=\"status\" style=\"width:20px; height:20px; \" class=\"circle red\"></div>", "<a runat=\"server\" id=\"link0\" href=\"MachineDetails.aspx?PageName=PCsByLocation.aspx&MachineName=AUBDW012\">AUBDW012</>", "Dye, Paul", "", "AsiaPacific / Australia / BrisbaneDistribution", "<div id=\"divonoffswitch\" class=\"onoffswitch\"><input type=\"checkbox\" name=\"onoffswitch\"...

ZeroMQ pattern for multiple asynchronous requests to single endpoint

I'm using zmq to develop a distributed application having the following network topology: a client node that initiates a request and a server node that replies to requests. Since the client is a node.js application I can't block after a send call to wait the response, so the scenario is...

Swift closures [weak self] and async tasks

Imagine a situation, when you want to asynchronously load some text from the server and display the result in the ViewController's UITextField. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //... some long running async operation if let textResponse = responseFromServer { dispatch_async(dispatch_get_main_queue(), { [weak self] () in self?.textField.text = textResponse }) } }) A.)...

Delphi Bug in Indy FTP List method?

I'm trying to generate a list of files matching a certain file mask and Indy falls over with this error EidReplyRFCError with message '.': No such file or directory. I've tried several variations and this is the result: FTP.List( aFiles, '', true ); => this works FTP.List( aFiles, '*.*', false...

Issues with AES Encryption using SynCrypto

Am trying to encrypt a file using SynCrypto.pas with AES 256, but it fails if I try to encrypt a file whose size is not a multiple of 16 bytes. The decrypted data contains junk. Example: Original string in txt file we are testing the file Encrypted String [ù[„|wáî}f *!4ìÙw¬•ü¨s...

Delphi - Use a string variable's name in assignfile()

Is it possible to use a variable in the assignfile command? Eg. f : Textfile ; sFile : string ; {contains 'MyFile.txt' as content} ... cFileDir = 'C:\Users\User\Desktop\Data Engine\Data\Country' ; ... Assignfile(f, cFileDir + '\' + sFile) ; ... I appreciate your help very much. if it's unclear I'll edit...

Asynchronously manipulating data from streamReader in F#

On the line of Read large txt file multithreaded?, I have the doubt of whether it is equivalent to pass to each thread an sliced chunk of a Seq and whether it will safely handle the paralellism; is it StreamReader thread-safe? Here is the code I am using to test...

C++ Ubuntu select() if serial interface has data on asynchronous read

I´m writing an asynchronous serial data reader class for Ubuntu using C++ and termios and I´m facing difficulties checking is there is data available. Here is my code: #include <iostream> #include <string> #include <sstream> #include <vector> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> class MySerialClass { public: MySerialClass(std::string port);...

do oncalculate fields in one table using values from another table

I am doing calculations in my KLOG table. However, my PRICES table has the data I need for the calculations in the KLOG table. Example : KLOG table has PRICE_ID field (integer). So does the PRICES table. So I am trying to do something like this (oncalculatefields of the KLOG...

How to use TThread.Synchronize() to retrieve the text of a TEdit control?

How can I use TThread.Synchronize() to retrieve the text of a TEdit control. Should I assign the TEdit text to a global variable or something?

Asynchronous TADOQuery's OnFetchComplete not synchonized to main thread

When using TADOQuery with [eoAsyncFetchNonBlocking] and attaching to OnFetchComplete event I found that OnFetchComplete is not executing in the main thread (tested in XE4 and XE8). I assume this a bug*, since most of us will do work in the UI on these type of event. I believe this to...

C# async await simple issue

I'm just learning about task, and async/await implementation and I'm struggling with a simple code example so I was hoping someone could share some lights as to what is going on. here's the code: public async Task<string> DoStuff() { Console.WriteLine("Long running op started"); var myString = await Task<string>.Run(() => {...

How to make my custom control be notified when his form or application receives and loses focus?

I want my control to receive distinct notifications only when it's parent form (not panel or something else, just the main form of this control) receives and loses focus. Doesn't matter if the focus is switched from another form of the application or between my application and other application, it...

Get file name from stats object

I use the fs.stat for getting information about file, now I want to get the file name from the stats object, I did some searching and I didnt find anything help. I will explain my code now, maybe someone will find another solution, this is all my code: function index(response,...

Function that returns intersection of two TShapes, including TPaths?

Anyone have any knowledge of a function that returns the intersection TPath for two TShapes? Especially one that returns the intersection TPath of two TPaths. For instance: pthIntersection := PathIntersection(Path1,Path2); ...

How to get enabled property of a control?

In Delphi it is possible to get the process name and class name of any control which is clicked system wide via windows api. process name: GetWindowThreadProcessId(Hwnd, ProcessId) by process ID one can get to the process name class name: SetLength(ClassName, 255); SetLength(ClassName, GetClassName(Hwnd, pchar(ClassName), 255)); Is there an easy...

How to remove duplicates in ListBox?

I use this code to remove duplicates: procedure TForm1.RemoveDuplicates(StrList : TStringList); var NoDuplicate: TStringList; i: Integer; begin NoDuplicate := TStringList.Create; try NoDuplicate.Sorted := True; NoDuplicate.Duplicates := dupIgnore; /// for i := 0 to StrList.Count - 1 do NoDuplicate.Add(StrList[i]) ; /// NoDuplicate.Sorted:= False; StrList.Assign(NoDuplicate) ; finally NoDuplicate.Free; end; end; It works...

Bulkheading strategies for Akka actors

I have a scenario where an important actor needs to make a call to a slow (15 - 20 seconds) remote system: // Non-actor code equivalent public Result makeSlowNetworkCall(Request request) { Result result = slowServiceClient.soooooSlow(request); // Could be up to 15 - 20 SECONDS (mehhhh) return result; } The Akka...

Why does the method return a string when return type is Task?

I have a question about asynchronous programming in C#. I want to know why a function that has a return type of Task has to return a string. So even through I returned a string, it gets wrapped into a Task again - why is that? Problem is that I...

Call Sync method call from Async Callback?

What happens when a synchronous method is called within an asynchronous callback? Example: private void AcceptCallback(IAsyncResult AR) { tcp.BeginReceive(ReceiveCallback); } private void ReceiveCallback(IAsyncResult AR) { tcp.Send(data); } A connection is accepted and the async receive callback is started. When the tcp connection receives data, it calls the receive callback. If...

HasValidFileNameChars fails for UNC files

For me HasValidFileNameChars function (in Delphi XE7) returns false for UNC files: B:= IOUtils.TPath.HasValidFileNameChars('\\ETA-PC\tests\test.ini', FALSE) B is false now This means that if you try to validate the filename that I show in my test (yes the file is real and as you can see its name is correct) HasValidFileNameChars...

Open file manage and get selected file

Using Delphi XE 8 and building Android app, can I browse files in the device by opening a certain file manager app installed on the device and then get back that selected file name and path ?

FastDOM - Read / write every 17ms?

FastDOM - a small library that batches DOM reads & writes into raf (requestAnimationFrames). I have read the code, however, I am struggling to understand how it works. Here are a few presumptions we have: - Browsers are generally set to 60fps - So in total, there can be...

connection refused when I try to connect client with server

I made a basic client / server datasnap applications and it work in local network through http but when I tried to connect from the internet I get connection refused, here are the steps I followed: I set at the server component TDSHTTPService to connect through port no 8081 then...