The following code has two incorrect diagnostics, S1186 and S2325.
public readonly struct EnterThreadPoolAwaitable : INotifyCompletion {
public EnterThreadPoolAwaitable GetAwaiter() => this;
public void GetResult() { } // Incorrect S1186
public bool IsCompleted => !Ui.IsMainThread(); // Incorrect S2325
public void OnCompleted(Action continuation) => _ = ThreadPool.QueueUserWorkItem(ThreadPoolPost!, continuation);
private static void ThreadPoolPost(object state) => ((Action)state)();
}
Awaiters are duck-typed in C#. Awaiters must have a 0-argument instance GetResult method with any return type, and must have a readable instance bool IsCompleted property. For all practical purposes, these members are interface-implementation members, and should be treated as such.
To a first approximation, any type returned from an instance GetAwaiter() method is an awaiter. For a stricter approximation, consider only GetAwaiter() methods defined on types passed to the await operator, but this has a higher risk of false positives.
I’m using SonarQube 8.26.0.14164 on Visual Studio 17.14.14 and Windows 11 24H2.