Page 1 of 5
Async question
Posted: Wed Mar 01, 2023 12:53 pm
by wriedmann
Hi,
I have the following code:
Code: Select all
async method _Connect( cHostName as string, cUserName as string, cPassword as string ) as Task<logic>
local lReturn as logic
local oTask as Task
_oClient := AsyncFtpClient{ cHostName, cUserName, cPassword }
oTask := _oClient:Connect()
await oTask
lReturn := _oClient:IsConnected
return lReturn
To be able to use the "await" keyword I need to flag the method as async.
If I understand that correctly, this method returns only when the task is finished.
But when I call that method from another one
Code: Select all
public method Connect( cHostName as string, cUserName as string, cPassword as string ) as logic
local lReturn as logic
self:_Connect( cHostName, cUserName, cPassword )
lReturn := _oClient:IsConnected
return lReturn
the compiler gives me the warning
Code: Select all
warning XS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
Where is my error/misunderstanding?
Thank you very much!
Wolfgang
Async question
Posted: Wed Mar 01, 2023 1:49 pm
by SHirsch
Hi Wolfgang,
change to return value just to LOGIC.
Stefan
Async question
Posted: Wed Mar 01, 2023 1:54 pm
by wriedmann
Hi Stefan,
thank you for your answer.
Unfortunately this does not work:
Code: Select all
error XS1983: The return type of an async method must be void, Task, Task<T>, a task-like type, IAsyncEnumerable<T>, or IAsyncEnumerator<T>
Wolfgang
Async question
Posted: Wed Mar 01, 2023 2:26 pm
by SHirsch
Hi Wolfgang
since you are not using the return value you can set the return type to VOID.
You are using
lReturn := _oClient:IsConnected
Otherwise you should have used
lReturn := await oTask
Stefan
Async question
Posted: Wed Mar 01, 2023 2:31 pm
by SHirsch
maybe you can also change your code
Code: Select all
method _Connect( cHostName as string, cUserName as string, cPassword as string ) as logic
local lReturn as logic
local oTask as Task
_oClient := AsyncFtpClient{ cHostName, cUserName, cPassword }
oTask := _oClient:Connect()
oTask:Wait()
lReturn := _oClient:IsConnected
return lReturn
Async question
Posted: Wed Mar 01, 2023 2:53 pm
by wriedmann
Hi Stefan,
when the return type is void, the compiler warning is gone. So I have a first solution.....
But when calling Wait() on the task, the task is not started, but waits.
I have now tried to call RunSynchronously() on the task, but that gives an exception:
Code: Select all
RunSynchronously kann nicht für eine Aufgabe aufgerufen werden, die nicht an einen Delegat gebunden ist, wie beispielsweise eine Aufgabe, die von einer asynchronen Methode zurückgegeben wird.
So I will solve with a void return value and store the return value in a property of my main object.
I have also tried with an out or ref parameter, but that does not works, as out and ref parameters are not permitted on async methods.
Thank you again - I have my solution now.
Wolfgang
Async question
Posted: Wed Mar 01, 2023 2:54 pm
by fxm
wriedmann post=25446 userid=336 wrote:
Code: Select all
public method Connect( cHostName as string, cUserName as string, cPassword as string ) as logic
local lReturn as logic
self:_Connect( cHostName, cUserName, cPassword )
lReturn := _oClient:IsConnected
return lReturn
One solution would be to get the result of the call to _Connect
Code: Select all
public method Connect( cHostName as string, cUserName as string, cPassword as string ) as logic
local lReturn as logic
local lConnectResult as logic
lConnectResult := self:_Connect( cHostName, cUserName, cPassword ):Result
lReturn := _oClient:IsConnected
return lReturn
or probably just
Code: Select all
public method Connect( cHostName as string, cUserName as string, cPassword as string ) as logic
local lReturn as logic
lReturn := self:_Connect( cHostName, cUserName, cPassword ):Result
return lReturn
Async question
Posted: Wed Mar 01, 2023 2:59 pm
by wriedmann
Hi Fergus,
the problem stays in the fact that the async method cannot return anything other than a void or task value.
If I can store the result in another place my code compiles without warning or error.
Wolfgang
Async question
Posted: Wed Mar 01, 2023 3:38 pm
by fxm
wriedmann post=25454 userid=336 wrote:Hi Fergus,
the problem stays in the fact that the async method cannot return anything other than a void or task value.
If I can store the result in another place my code compiles without warning or error.
Wolfgang
I think I must have missed the point. In any case, this code compiles without warnings..
Code: Select all
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
using System.Threading.Tasks
FUNCTION Start() AS VOID STRICT
Console.WriteLine("Hello World!")
LOCAL t AS Test
t := Test{}
t:Connect()
Console.ReadKey()
CLASS Test
ASYNC METHOD _Connect() AS Task<LOGIC>
AWAIT Task.Delay(1000)
RETURN TRUE
METHOD Connect AS LOGIC
LOCAL lReturn AS LOGIC
lReturn := SELF:_Connect():Result
RETURN lReturn
END CLASS
Async question
Posted: Wed Mar 01, 2023 3:57 pm
by HansjoergP
Your call self:_Connect needs an await. If you need an synchronous call you can use
self:_Connect( cHostName, cUserName, cPassword ).Result
With the Result Call you have to be carefull, because in some situation it can result in an dead lock