I receive the following compilation error from ccrewrite when using Code Contracts 1.4.51019.0 in VS2012 on Windows 7 x64: "The method or operation is not implemented."
It appears to be caused by a combination of property accessors and the use of async
methods which lack an inner await
.
Reproduction steps:
Create a new class library with 'Full' Runtime Contract Checking enabled:
namespace CodeContractsAsyncBug
{
using System.Threading.Tasks;
public class Service
{
// Offending method!
public async Task ProcessAsync(Entity entity)
{
var flag = entity.Flag;
}
}
public class Entity
{
public bool Flag { get; set; }
}
}
Has anyone else experienced this?
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
A method in C# is made an asynchronous method using the async keyword in the method signature. You can have one or more await keywords inside an async method. The await keyword is used to denote the suspension point. An async method in C# can have any one of these return types: Task, Task<T> and void.
The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete.
The Action method only works on synchronous methods. For asynchronous methods it does not work. To understand why, we have to dive a bit deeper into asynchronous methods and how the compiler generates them. An asynchronous method in C# is split on the await calls into multiple synchronous parts by the compiler.
This appears to be fixed in version 1.5 of Code Contracts.
An async
method that does not await
is usually indicative of a programming error. There is a compiler warning that will inform you of this situation.
If you wish to synchronously implement a method with an asynchronous signature, the normal way to do this is to implement a non-async
method and return a Task
, such as Task.FromResult<object>(null)
. Note that with this approach, exceptions are raised synchronously instead of being placed on the returned Task
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With