Uh oh!
There was an error while loading. Please reload this page.
Resolve dllimport.cpp runtimeasync todos - #122466
Conversation
There was a problem hiding this comment.
Pull request overview
This PR resolves TODOs related to async method handling in the P/Invoke implementation. The changes replace placeholder TODO comments with explanatory comments about why async methods are not supported for P/Invoke scenarios, convert some assertions to preconditions, and adjust error handling in one case to defer exception throwing to the IL stub generation path.
Key changes:
- Adds PRECONDITION checks for async methods in constructor contracts and function preconditions
- Replaces TODO comments with clarifying comments explaining that async P/Invoke methods should use async variant stubs that call task-returning interop stubs
- Changes
MarshalingRequiredto return TRUE for async methods (to trigger proper exception later) instead of throwing immediately
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
VSadov
commented
Dec 11, 2025
Interestingly it allows Synchronized. [MethodImpl(MethodImplOptions.Synchronized)][DllImport("kernel32.dll")]privatestaticexternboolQueryPerformanceFrequency(outlongfrequency);It results in Perhaps In theory we could just ignore The runtime could be more strict than the spec and making it an error as it is the case with |
VSadov
commented
Dec 11, 2025
I can think of only two ways to get async involved with DllImport.
Roslyn does not like adding The runtime also does not allow non-task Async methods outside of corlib, so maybe that will error out first. [MethodImpl(MethodImplOptions.Async)][DllImport("kernel32.dll")]privatestaticexternboolQueryPerformanceFrequency(outlongfrequency);
[DllImport("kernel32.dll")]privatestaticexternTaskQueryPerformanceFrequency(outlongfrequency);[DllImport("kernel32.dll")]privatestaticexternValueTaskQueryPerformanceCounter(outlongcounter);I am not sure if either of above can work right now. |
jkoritzinsky
commented
Dec 11, 2025
@VSadov good point on MethodImpl attribute. I'll add some tests to make sure we don't crash. |
…th the async bit set.
jkoritzinsky
commented
Dec 15, 2025
@VSadov I've rewritten this PR to have the following implementation: Loading a P/Invoke with the async bit set fails to load. The async variant for a P/Invoke method (if even usable) will not be considered a P/Invoke (similar to how we handled this for COM interop). Jitting a method with UnmanagedCallersOnly with the async bit set fails with InvalidProgramException. dllimport.cpp asserts that it never sees a method with the async bit set. |
The The scenario like the following is testable though. It is also a preexisting scenario, so regression is a bigger deal. Perhaps we should have a test. [DllImport("kernel32.dll")]privatestaticexternTaskQueryPerformanceFrequency(outlongfrequency);[DllImport("kernel32.dll")]privatestaticexternValueTaskQueryPerformanceCounter(outlongcounter);Otherwise looks good to me. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Skip new UCO negative test on Mono
Uh oh!
There was an error while loading. Please reload this page.
Roslyn should never mark a P/Invoke or a delegate's
Invokemethod as an async method, so there's not a good way to add tests without writing them in IL and it doesn't seem particularly useful to do so.Fixes#121758