I am are trying to use TMSFNCCloudMicrosoftOutlookMail class, but I have a problem.
The existing code assumes blocking usage. Previously, I would call send, code was blocking and would return true/false to indicate success/failure.
With your class the execution is non blocking and there is an event to be used instead.
How can I use your component and implement proper blocking/waiting until sending has succeeded or failed ?
I noticed event is called from Synchronize so I can't use TEvent, nor simple Sleep, as ProcessMessages is required for Synchronize to work.
Do you have any suggestion for more elegant waiting solution that does not require ProcessMessages ?
Can also tell that change the code require a major refactoring as there is other emailing solutions as well that use blocking mode. The calling code should just call email method and not be aware if blocking/nonblocking is used.
Please note that TTMSFNCMicrosoftOutlookMail works asynchronously by design. Unfortunately there is currently no built-in blocking execution available.
Like you mentioned, you have to use an event to determine when the execution has finished.
However, this is a good suggestion and we'll consider adding a blocking execution feature in a future version.
RequestResult.Async property in TTMSFNCCloudMicrosoftOutlookMail.
Itested to set it to false but didn't work. So I assume the intention of that is something else.
I note that the backgroundthread is calling CheckSynchronize whenemail is sent and the event for result is called.
How can I check when this is done from main thread to simulate blocking behaviour ?
What I tried so far:
function TATMail.SendCloudMail(const aReceiver, aReplyTo, aCc, aSubject, aBody,
aAttachments: string; ACallBack: TEMailCallBack; out AErrorMessage: string): Boolean;
var
oOutLook: TOutlookEmail;
begin
oOutLook := TOutlookEmail.Create(aReceiver, aReplyTo, aCc, aSubject, aBody, aAttachments, ACallBack);
// TTMSFNCCloudMicrosoftOutlookMail has only none blocking implementation
// Therefore it simulate blocking by waiting on threads call to Synchronize
if not Assigned(ACallBack) then
begin
var oEvent: TEvent;
oEvent := TEvent.Create;
try
oEvent.ResetEvent;
while oEvent.WaitFor(200) <> wrSignaled do
begin
CheckSynchronize(100);
end;
finally
AErrorMessage := oOutLook.fMessage;
Result := oOutLook.fSuccess;
FreeAndNil(oEvent);
end;
end
else
Result := True; // Doesn't matter. None blocking code should never check result.
end;