microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.79k stars 148 forks source link

async Task #556

Closed flat-eric147 closed 10 months ago

flat-eric147 commented 10 months ago

Hello,

I usually access some C# properties through ClearScript like:

someCSharpclassInstance.aProperty = "Hello World"

The property is an ordinary property like so: public string aProperty { get { // assign something } set { // return something } }

Since I am porting a large amount of C# code to use the async/await paradigm, I cannot use await in the property setter. In some cases the setter might trigger loading an image from a web resource.

I could replace the above assignment with dedicated async setter functions like:

someCSharpclassInstance.SetaProperty("Hello World")

where on the C# side I would have something like:

public async Task SetaProperty(string value) { await dosomethingThatTakesAWhile(value) }

which is less intuitive and would break existing (script) code.

What would be your recommendation/good practice to this "problem"? Can I somehow overload the assignment operator instead? And how would I await a c# async method in CleacScript/V8?

I know there are methods to force the async methods to run synchronously form a non async method, but that might lead to deadlocks.

Thank you!

ClearScriptLib commented 10 months ago

Hi @flat-eric147,

Since I am porting a large amount of C# code to use the async/await paradigm, I cannot use await in the property setter. In some cases the setter might trigger loading an image from a web resource.

Unfortunately, in both C# and JavaScript, the expression foo.bar = baz always evaluates to baz. There's no way for a property setter to return a task or promise that tracks the operation of the setter itself, nor is there a way to override the assignment operator in a way that would allow it.

Therefore, as far as we can tell, there's no way to add nonblocking behavior to settable properties without affecting their callers – in either language – so the first step is to decide how exactly you want your settable properties to behave in your new async-aware, nonblocking codebase.

And how would I await a c# async method in CleacScript/V8?

The easiest way would be to enable automatic task-promise conversion via V8ScriptEngineFlags.EnableTaskPromiseConversion. That way you could simply await tasks in script code. Let us know if you need an example.

Good luck!

flat-eric147 commented 10 months ago

Thank you!