Over the last year I’ve been dabbling in the dark arts of GraphQL. As a web api interface, its easy to consume and utilize, but I consider myself a back end developer first and for most. I have been spending my time learning how to build a GraphQL server implementation utilizing .NET Core with GraphQL.NET. I’ve pulled down the project’s recent code, launched the harness project, and was immediately met with an ASP.NET Core error.
System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)
at System.IO.StreamReader.ReadSpan(Span`1 buffer)
at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at Example.GraphQLMiddleware.Deserialize[T](Stream s) in /Users/khalidabuhakmeh/Projects/dotnet/graphql-dotnet/src/GraphQL.Harness/GraphQLMiddleware.cs:line 93
at Example.GraphQLMiddleware.ExecuteAsync(HttpContext context, ISchema schema) in /Users/khalidabuhakmeh/Projects/dotnet/graphql-dotnet/src/GraphQL.Harness/GraphQLMiddleware.cs:line 54
at Example.GraphQLMiddleware.Invoke(HttpContext context, ISchema schema) in /Users/khalidabuhakmeh/Projects/dotnet/graphql-dotnet/src/GraphQL.Harness/GraphQLMiddleware.cs:line 41
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
It turns out, starting in .NET Core 3.0, all synchronous operations on the request are turned off by default.
AllowSynchronousIO is a option in each server that enables or disables sync IO APIs like HttpReqeuest.Body.Read, HttpResponse.Body.Write, Stream.Flush, etc.. These APIs have long been a source of thread starvation and application hangs. Starting in 3.0.0-preview3 these are disabled by default. –Chris Ross
If you are seeing this error after upgrading your project to .NET Core 3.0, it is likely you are running on these .NET server implementations.
- Kestrel
- HttpSys
- IIS in-process
- TestServer
Errors can revolve around ReadAsync
, WriteAsync
, and FlushAsync
with outputs similar to what is listed below.
Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.
As a temporary workaround, you can set the value of AllowSynchronousIO
in your ConfigureServices
method found in your Startup
class.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// If using IIS:
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// other services
}
It isn’t a great workaround, but it will keep you moving forward. The better solution is to upgrade your libraries and perform all your actions asynchronously. I hope this helped!