Async/Await questions

Hi
I’ve been investigating Async/Await available in Oxygene. From what I can see, they nearly do the same as the C# 5 keywords, but not quite. For instance in C#5 if I call an async method that awaits on another async method that itself also has an await, the first method only continues, after the await of the 2nd methods awaited code has completed. But in Oxygene the first methods awaited code seems to start as soon as the 2nd method finished the code before it’s await. Is this correct? If so is there any plans to have similar functionality that C#5 async/await gives you but for Oxygene. The confusion is that now a lot of .net objects use the C#5 async/await pattern and I can’t quite figure out how to do the same using Oxygene without resorting to Task.ContinueWith etc.
Am I not understanding something correctly?

Alex

alex: Oxygene has had an “async” keyword since about 2.0 times which behaves quite different from the newly introduced c# async keyword. The issue is that in oxygene, async methods actually run async. In c# the keyword is used by the compiler to tell it that “await” is allowed, nothing more. If you want the exact same behavior as c# does, just leave async out in Oxygene. If you want it to run on another thread right away (in which case “await” doesn’t sync back to the main thread after it evaluated) then use async and avoid await.

Hi ck
OK, understood so far. But doesn’t the C# async keyword also turn the result type of the method to Task or Task. How would you acheive the same with Oxygene? Do I have to wrap the whole method into a Task.Factory.StartNew etc etc? As either it’s invalid code or a problem with the compiler, but if I have a method decorated with async and try to use await in said methods body then the compiler throws the following error
"error E0: Internal error: Object reference not set to an instance of an object"

Alex

that sounds like a bug. Can you paste the exact code you use?

as for the return type: just define it:

type
  ConsoleApp = class
  public
    class method Main(args: array of String);

    class method Awaiting: Task;
  end;

implementation

class method ConsoleApp.Main(args: array of String);
begin
  // add your own code here
  Console.WriteLine('Hello World.');
end;

class method ConsoleApp.Awaiting: Task;
begin
  await new Task(-> Console.WriteLine('test'));
  exit 'test';
end;

Hi ck
Try to compile the following

namespace AsyncAwaitTest;

interface

uses 
  System.Threading, 
  System.Threading.Tasks;

type
  ConsoleApp = class
  private
    class method Main(args: array of String);
    class method MainAsync(); async;
  public
  end;

implementation

class method ConsoleApp.Main(args: array of String);
begin
  // add your own code here
  Console.WriteLine('Hello World.');
  MainAsync();
  Console.Write('>');
  Console.ReadLine();
end;

class method ConsoleApp.MainAsync();
begin
  Console.WriteLine('Enter MainAsync');
  //Thread.Sleep(2000);
  await Task.Delay(2000);
  Console.WriteLine('Leave MainAsync');
end;

end.

I get the following error

error E0: Internal error: Object reference not set to an instance of an object.

thanks. Logged as bugs://62008.

Is Task.Delay supposed to be using a Static Class Task? If not, don’t you need to “new it up”? As in the previous example?

If you don’t make a NEW Task, isn’t that why the error says you don’t have an instance?

Task.Delay is a class method and has nothing to do with the compiler error.

The error is related a bug in the compiler when mixing async with await. The fix is to drop the ‘async’ keyword.