Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async await support in Functions #57

Open
aligin opened this issue Jan 30, 2017 · 5 comments
Open

Async await support in Functions #57

aligin opened this issue Jan 30, 2017 · 5 comments

Comments

@aligin
Copy link

aligin commented Jan 30, 2017

Hello. I've succesfully integrated DynamicExpresso (.NET Core) in my project, but there is a question with the Functions, that returns Task. Is there support for this kind of Expressions?

Example:

var target = new Interpreter();
Func<int, Task<bool>> func = async (x) => await _someHttpService.Get(x);
target.SetFunction("foo", func);
var parsedExpression = target.Parse("true && foo(1)", parameters));

Currentry I receive Exception

The binary operator AndAlso is not defined for the types 'System.Threading.Tasks.Task`1[System.Boolean]' and 'System.Threading.Tasks.Task`1[System.Boolean]'.
@davideicardi
Copy link
Member

Yes, currently this is not supported. Probably this can be written using:

target.Parse("true && await foo(1)", parameters));

Or maybe adding a ParseAsync function ... but unfortunately both methods are currently not supported.

The only solution for now is to rewrite your function with sync methods:

Func<int, bool> func = (x) => _someHttpService.Get(x).Result;

@aligin
Copy link
Author

aligin commented Jan 31, 2017

@davideicardi Thanks for the answer. I've already done in sync mode. I realized that the targeted .NET Framework was 4.0. And this version does not contain async await. I think cause of .NET 4.0 suport ParseAsync will be the best choise.

@huangyedie
Copy link

Yes, currently this is not supported. Probably this can be written using:

target.Parse("true && await foo(1)", parameters));

Or maybe adding a ParseAsync function ... but unfortunately both methods are currently not supported.

The only solution for now is to rewrite your function with sync methods:

Func<int, bool> func = (x) => _someHttpService.Get(x).Result;

Is it supported now? Async await

@metoule
Copy link
Contributor

metoule commented Jul 23, 2022

No, async / await is not supported, and probably never will be. When you write an async method, the compiler performs a LOT of things (creating a class to hoist captured variables, etc), which can't easily be done.

Under the hood, we're using Linq expression trees, which doesn't provide any method to do that.

You can check this stackoverflow question

@MarcusGoldschmidt
Copy link

This is a workaround that worked for me

store the results from the async task before executing the invoke of the Lambda

var interpreter = new Interpreter();

var dictionary = new Dictionary<string, double>();

interpreter.SetFunction("ASYNC_TASK", () => dictionary["ASYNC_TASK"]);

var parsed = interpreter.Parse("ASYNC_TASK() + 1");

// Simulate an async function
dictionary["ASYNC_TASK"] = await Task.FromResult(10);

var result = parsed.Invoke();

Assert.Equal(11.0, result);

Also, you can get the Functions that Lambda contains

List<Identifier> functionsUsedByExpression = parsed
    .Identifiers
    .Where(e => e.GetType().Name == "FunctionIdentifier")
    .ToList();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants