-
Notifications
You must be signed in to change notification settings - Fork 693
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
Calling .NET async/await functions #604
Comments
Currently C# async to python async bridge is not implemented. And it's very hard task, and there are too many abstraction leaks in both languages. |
(I agree with your assessment of abstraction leaks.) So in Python you would simply call the function like so?
|
f=MyDll.Foo("a").Result; |
I knew that :-) (There's actually a problem with |
Does GetAwaiter().GetResult() works better? |
If you need asynchronous behavior, you can use |
I'm not going to speak to whether this is a good idea or not, but a potential solution is to wrap all calls using an AnyIO BlockingPortal. The above authors are correct that the abstractions are leaky and deadlock is a potential (you probably want to be careful to call ConfigureAwait(false) liberally in your .NET libraries. If you don't know why, you probably shouldn't be using this). Performance may be terrible, I didn't test it. Tested on Python 3.8 with pythonnet 3.0.0a2 on Linux using DotNet Core 6. import anyio
from clr_loader import get_coreclr
from pythonnet import set_runtime
# I'm testing on .NET Core with 3.0.0a2
rt = get_coreclr("conf.json")
set_runtime(rt)
import clr
import System
from System.Threading.Tasks import Task
from System.IO import File
# Create an alias for Action with one generic attr
Action1 = getattr(System, "Action`1")
async def call_async(func, *args, **kwargs):
async with anyio.from_thread.BlockingPortal() as portal:
result = func(*args, **kwargs)
result.ContinueWith(Action1[Task](lambda t: portal.start_task_soon(portal.stop)))
await portal.sleep_until_stopped()
if hasattr(result, "Result"):
return result.Result
else:
result.Wait()
async def main():
await call_async(Task.Delay, 1000)
print("I waited")
contents = await call_async(File.ReadAllLinesAsync, __file__)
print(f"My First Line is {contents[0]}")
# I return errors too
await call_async(File.ReadAllLinesAsync, "BOGUS")
if __name__ == '__main__':
# call_async should work from trio or asyncio
import trio
trio.run(main) |
Another option which avoids Task.Result or Task.Wait to block current thread (since by the time it used, task is completed):
For awaiting async C# method in python, you could do something like:
|
Some reading in case somebody wants to take on implementing Python's
|
Note that in my sample code I only ever call |
Environment
Details
Say I load a .NET DLL like so:
and say in MyDLL I have methods of the form:
Should it be possible to invoke this from Python? Is there a different syntax for this?
The text was updated successfully, but these errors were encountered: