15

Good day! I am trying to write an anonymous method using lambda expressions which would return an object from an async task. I would like to do this in the constructor, so that is the reason I can't make its parent method async.

The ReadJsonAsync method returns a Session object. I will show you the relevant code:

Session session;
fileService = new FileService();
session = async () =>  { return await fileService.ReadJsonAsync() };

Thanks in advance!

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
masm64
  • 1,222
  • 3
  • 14
  • 31
  • Is `Session` a delegate type? What are you trying to do? – Yuval Itzchakov Nov 15 '14 at 14:32
  • I would like an anonymous method which would return a "Session" object. Sorry I am not really good at this, but I am trying to learn and get better – masm64 Nov 15 '14 at 14:33
  • 1
    That's fine, but then you're storing the result in a `Session` object, which makes no sense. You're trying to store a "method returning Session" into a "Session". You should be storing it into a delegate (which is how you store methods). – Raymond Chen Nov 15 '14 at 14:36
  • 1
    It's unrelated to your problem, but `return await fileService.ReadJsonAsync()` is redundant; you can just return `fileService.ReadJsonAsync()` directly and remove the `async` modifier. – Thomas Levesque Nov 15 '14 at 14:40
  • Does this answer your question? [Cannot convert lambda expression to type 'System.Delegate'](https://stackoverflow.com/questions/9549358/cannot-convert-lambda-expression-to-type-system-delegate) – StayOnTarget Jan 22 '21 at 12:51

2 Answers2

15

If you want an Anonymous Method, you'll have to declare one which returns a Task<Session> as it is marked with the async modifier, hence must return a void (only for async event handlers), Task or Task<T> :

Func<Task<Session>> anonFunction = async () => await fileService.ReadJsonAsync();

If all you do is run ReadJsonAsync, you may also save yourself the state machine generation like so:

Func<Task<Session>> anonFunction = fileService.ReadJsonAsync;

Then you can await on it higher up the call stack:

Func<Task<Session>> anonFunction = fileService.ReadJsonAsync;
await anonFunction();
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
9

To add to Yuval's useful answer, if you just want to await an inline function, then the magic syntax is:

await ((Func<Task>)(async () =>
{
    //async function code
}
))();

Note the extra brackets on the end to call the lambda immediately after declaration. Obviously if your function returns a type, then it would be Func<Task<Whatever>>

Useful if you're using Task.WhenAny() for example to await both an inline function and a timeout task.

GazTheDestroyer
  • 20,722
  • 9
  • 70
  • 103