Entity framework 6 async/await fail in parallel request - asp.net

I'm working in ASP.NET 4.6 with EF 6 to a new Web Api 2 project, I've read a lot of articles that describes the async/await pattern and It's clear that for a lot of requests this pattern increase performance for a lot of reasons.
So I decided to use it for the first time.
In decided to create a Biz project and a DAL project here an example.
This is controller method:
[HttpGet]
public async Task<bool> CheckValueValidity(string value, string type)
{
return await _accountsBiz.CheckValueTypeValidity(value, type);
}
I instance biz object in controller constructor.
This is the BIZ:
public async Task<bool> CheckValueTypeValidity(string value, string type)
{
bool isValid = false;
switch (type.ToLower())
{
case "email":
isValid = await _accountsRepository.CheckEmailValidity(value);
break;
case "username":
isValid = await _accountsRepository.CheckUserNameValidity(value);
break;
}
return isValid;
}
I instance the repository in the BIZ constructor.
Finally this is the DAL method:
public async Task<bool> CheckEmailValidity(string email)
{
using(MyEntities db = new MyEntities())
{
return await db.AspNetUsers.CountAsync(u => u.Email == email) > 0 ? false : true;
}
}
And all it seems to work perfectly until I made two request at same time, one of these return the correct value the other say
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
I made the requests from two different client so the context should be different. should....
I don't know how to fix it. I read a lot and my code seems to be correct.
The question is WHY throw this error? I can't understand
Thanks for help in advice.

Ok found the error in the execution flow there is a method that use DbContext without using block.... My mistake but now it's clear that context must be disposed each request!

Related

GraphQL .NET: middleware problems with singleton schema

I'm using GraphQL on a .NET core website/controller. The schema is quite large, such that the constructor takes about a second to run. I couldn't have that kind of overhead on every request, so I created the schema as a singleton, shared between all requests.
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
{
var executionOptions = new ExecutionOptions {
Schema = this.Schema, // dependency injected singleton
/* ... */
};
// ...
executionOptions.FieldMiddleware.Use(next => context =>
{
return next(context).ContinueWith(x=> {
var result = x.Result;
return doStuff(result);
});
});
var result = await new DocumentExecuter().ExecuteAsync(executionOptions).ConfigureAwait(false);
// ...
}
This worked most of the time, but it caused random problems with the middleware. Sometimes the middleware would start running twice for each element, which would usually cause an error the second time the middleware ran.
Looking at the source, it appears the middleware is being applied to the schema during the life cycle of a request, and then somehow rolled back at the end I guess? At least I'm assuming that's how the public void ApplyTo(ISchema schema) member is being used, although I'm not sure how the "rollback" part was happening.
This gave me an idea of how to solve the problem by pulling the middleware out of the view and put it in the schema constructor, like this:
public class MySchema : Schema
{
public MySchema()
{
this.Query = new MyQuery();
this.Mutation = new MyMutation();
var builder = new FieldMiddlewareBuilder();
builder.Use(next => context =>
{
return next(context).ContinueWith(x=> {
var result = x.Result;
return doStuff(result);
});
});
builder.ApplyTo(this);
}
}
So now the middleware is baked directly into the schema when the singleton is constructed, and the controller doesn't have to do anything.
This appears to have completely solved the problem. I'm not sure if there are other things in graphql-dotnet that mutate the schema during the request life cycle. If anyone knows of any other problems that might occur with a singleton schema I'd love to hear it!

What are the recomendation for developing .net core 2.2 web api for following bulleted points? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am developing a new WebApi using .NetCore2.2, Autofac4, Dapper. There are few very basic questions because this is my first WebApi project. As part of this project I have to write both unit-test and integration-test.
My questions are as follows (Sample Code is give below):
What is recommended return type between "Task< IActionResult >" and "Task< IEnumerable >"?
Recommended object Scope of the dependencies in startup class for my project?
Do I really need UnitOfWork for this given project structure?
What are the flaws if I follow this design?
Is there any better way to design this API?
As TDD do I need write test cases for API layer(Controller) and Infrastructure layer only or Doman Layer (it doesn't have any logic) as well?
What are the scenario I must include in my controller unit test?
Domain Layer:
[Table("Movie")]
public class Movie
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID {get;set;}
public string Title {get;set;}
}
public interface ICommandRepository<T> where T : class
{
Task CreateAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(T entity);
}
public interface IQueryRepository<T> where T : class
{
Task<IEnumerable<T>> GetAllMoviesAsync();
Task<IEnumerable<T>> GetMoviesByTitleAsync(string title);
Task<T> GetMovieByIDAsync(int id);
}
Infrastructure Layer:
public class MovieCommandContext : DbContext
{
public MovieCommandContext(DbContextOptions<MovieCommandContext> options)
: base(options)
{}
public DbSet<Movie> Movies { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
public class MovieQueryContext : IDisposable
{
private readonly IDbConnection connection;
public MovieQueryContext(string connectionString)
{
connection = new SqlConnection(connectionString);
}
public async Task<IEnumerable<Movie>> GetAllMovies()
{
// Use Dapper->QueryAsync
throw new NotImplementedException();
}
...
public void Dispose()
{
if (connection?.State == ConnectionState.Open)
connection.Close();
}
}
public class MovieCommandRepository : ICommandRepository<Movie>
{
private readonly MovieCommandContext context;
public MovieCommandRepository(MovieCommandContext dbContext)
{
context = dbContext;
}
public async Task CreateAsync(Movie movie)
{
await context.AddAsync<Movie>(movie);
await context.SaveChangesAsync();
}
public async Task UpdateAsync(Movie movie)
{
var entity = context.Attach<Movie>(movie);
context.Entry<Movie>(movie).State = EntityState.Modified;
await context.SaveChangesAsync();
}
public async Task DeleteAsync(Movie movie)
{
context.Remove<Movie>(movie);
await context.SaveChangesAsync();
}
}
public class MovieQueryRepository : IQueryRepository<Movie>
{
private readonly MovieQueryContext context;
public MovieQueryRepository(MovieQueryContext dbContext)
{
context = dbContext;
}
public async Task<IEnumerable<Movie>> GetAllMoviesAsync()
{
return await context.GetAllMovies();
}
public async Task<IEnumerable<Movie>> GetMoviesByTitleAsync(string title)
{
return await context.GetMovieByName(title);
}
public async Task<Movie> GetMovieByIDAsync(int id)
{
return await context.GetMovieByID(id);
}
}
API Layer:
[Route("api/sample")]
[ApiController]
public class SampleController : ControllerBase
{
private readonly ICommandRepository<Movie> movieCommand;
private readonly IQueryRepository<Movie> movieQuery;
public SampleController(ICommandRepository<Movie> command, IQueryRepository<Movie> query)
{
movieCommand = command;
movieQuery = query;
}
[HttpGet]
public async Task<IActionResult> GetMoviesAsync()
{
try
{
var movies = await movieQuery.GetAllMoviesAsync();
return Ok(movies);
}
catch
{
// TODO: Logging
return BadRequest();
}
}
[Route("{name:alpha}")]
[HttpGet]
public async Task<IActionResult> GetMoviesByTitle(string movieTitle)
{
try
{
var movies = await movieQuery.GetMoviesByTitleAsync(movieTitle);
return Ok(movies);
}
catch
{
// TODO: Logging
return BadRequest();
}
}
[Route("{movieID:int:min(1)}")]
[HttpGet]
public async Task<IActionResult> GetMovieByID(int movieID)
{
try
{
var movie = await movieQuery.GetMovieByIDAsync(movieID);
return Ok(movie);
}
catch
{
// TODO: Logging
return BadRequest();
}
}
[Route("")]
[HttpDelete("{id:int:min(1)}")]
public async Task<IActionResult> Delete(int id)
{
try
{
var movie = await movieQuery.GetMovieByIDAsync(id);
if (movie == null)
return BadRequest();
await movieCommand.DeleteAsync(movie);
return Ok();
}
catch
{
// TODO: Logging
return BadRequest();
}
}
}
Startup.cs:
private void ConfigureContainer(ContainerBuilder builder)
{
var contextOptions = new DbContextOptionsBuilder<MovieCommandContext>()
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
.Options;
builder.RegisterType<MovieCommandContext>()
.WithParameter("options", contextOptions);
builder.RegisterType<MovieQueryContext>()
.AsSelf()
.WithParameter("connectionString",Configuration.GetConnectionString("DefaultConnection"));
builder.RegisterType<MovieCommandRepository>().As<ICommandRepository<Movie>>();
builder.RegisterType<MovieQueryRepository>().As<IQueryRepository<Movie>>();
}
Point 1:
You should return an IActionResult to return a propper Http response, instead of returning the Task<IEnumerable<Movie>>. That way you guarantee the S and the I of SOLID principles
Point 2 & 3:
see here: Entity Framework Core service default lifetime
Point 4:
IQueryRepository as some bad methods names. The names are tight coupled with domain concepts and they should not.
You are failing the Separation of concerns ( the S of SOLID).
ICommandRepository as an Add method that is being expose to some controller and not being used ( same as Update) here you are failing on the Interface segregation.
MovieQueryContext does not implement IDisposable pattern correctly please see here!
MovieQueryContext is different from MovieCommandContext on the way it initializes. Why? You should try to be coherent the way you design you types because it will give you reusability and apply the DRY principle.
Consider the effort you will need to to if the access to the database change to mongodb. Or if the access to the database changes to a remote service How many changes, and where do you do does changes to support that?
If Movie is a Domain Type it should not have attributes to any specific database access. keep it POCO as possible.
Point 5:
To design your API consider this post. The way you inject your dependencies should consider the lifetime of those objects. Keep in mind that in aspnet.core ApiControllers lifetime is per request. The way you manage your resources to access database should take that into consideration.
If you are considering CQRS, the controllers should be diferent. Keeping in mind the Separation of concerns regarding those responsabilities. One controller would have the responsability to expose some query API, and the other to process commands. There are good frameworks to support CQRS see this scott hanselman post.
Constraints exists on Route attribute not on Verbs.
Logging and Exception handling should be done on an ActionAttribute or on some Especific Middleware, because they are considered to be cross cutting concerns.
Delete Action does not comply to the Http protocol. please consider http rfc:
GetMoviesByTitle Action does not have the name parameter.
Point 6:
Unit tests should test business logic, mocking all the external dependencies with values relevant to the test in place. TDD methodology considers 3 main steps ( here for more details):
the first step consists on implementing the unit tests so it fails
Iterate on implementation of the method being test until it passes with success
Improve the implementation of the method being test
If you want to test your ApiController as being used with all the middleware integrated you need to have that environment put in place without using an actual server that open ports. To do that please consider the usage of TestServer ( see here and here )
1. What is recommended return type between "Task< IActionResult >" and "Task< IEnumerable < Movie > >"?
Even though the API allows you yo use the interface IActionResult, I wouldn't use it at all. Why? Semantics, the only way to know what the true return is, is to see the implementation. It's clearer if the returns is Task< IEnumerable< Movie>>.
If you need to throw a BadRequest or other http code, use the asp.net pipeline to handle this for you. See Notes below.
When using whatever tool to generate some sort of documentation of this API it won't help hiding the real result.
2. object Scope of the dependencies in startup class for my project?
Avoid sharing state between calls, to avoid future issues with synchronization just stick to scope dependencies per request. This may be a performance issue if you have a lot of requests, you can always change this later on. If it's an issue at all.
3. I really need UnitOfWork for this given project structure?
4. What are the flaws if I follow this design?
5. Is there any better way to design this API?
In hope of answering the above 3 questions. The problem I see is extending the functionality around Movie model. e.g. add a fourth action on ICommandRepository.
It seams it will grow vertically. It will only be a problem if multiple classes implement this interface, because they will all need to change. (Interface Segregation Principle)
A way to solve this is to use the Mediator pattern. Your controller will receive the mediator and the mediator will deliver the message to whoever handles it. With this type of solution you could have a class per operation and therefore your system can grow horizontally as new classes are added to the system. (Open Close Principle)
In time, you'll see that a lot of functionality can be reused and adding features is just a matter of configuration.
6. As TDD do I need write test cases for API layer(Controller) and Infrastructure layer only or Domain Layer (it doesn't have any logic) as well?
The idea of Testing in general is to test behavior, when TDDing that should be your mindset. In my experience I found that testing the whole behavior is better than multiple parts of the same behavior.
In this case, the API Layer is part of the infrastructure as is the persistence layer. They should have their own tests, the business rules (Application layer) should have their own tests. The application layer is what you want to last forever. The Api will change as technologies appear (windows forms, web forms, web apis, etc.) Regarding databases as well, you don't know if you want to stick with EF forever.
If the domain layer doesn't provide any behavior then there is nothing to test.
7. What are the scenario I must include in my controller unit test?
I would test using asp.net TestHost:
https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2
Test the if routing is correct, test failing scenarios and successful scenarios.
Some notes:
An exception in the Controller does not mean a BadRequest.
Logging is a cross cutting concern, don't just do it everywhere.
Either use the asp.net pipeline or just move this concern to
application layer.
It appears that MovieQueryRepository does nothing, so you don't need it.
This is just some remarks about your questions, there is much more to it. Just remember to keep things simple and organized.
Hope it helped, let me know!

Web API Service - How to use "HttpContext.Current" inside async task

I'm using a "Post" async method of webApi rest service:
public async Task<object> Post([FromBody]string data)
{
object response = ExecuteServerLogics(data);
return response;
}
This above code worked good but in some of the client's calls, we experienced performance issues.
After reading some articles here, i've noticed that our webApi rest service,
is not really working asynchronously with its incoming web requests,
because we forgot to use async/await pattern :
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
return ExecuteServerLogics(data);
});
return response;
}
After this fix we noticed the performance got better,
but we found another critic problem:
when accessing HttpContext.Current - it returns Null reference:
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
var currentContext = HttpContext.Current; // Returns Null!
return ExecuteServerLogics(data);
});
return response;
}
We tried to found a solution for it, and in most posts we found that we should pass the
worker thread's HttpContext reference into the inner Task that executes the server logics.
The problem with this solution is that the server's logics methods, use many static classes that use
"HttpContext.Current" such as -
Loggers calls.
static security classes that retrieves the user.identity
static security classes that retrives the incoming request's session data, etc.
Therefore, passing the "HttpContext.Current" reference of the worker thread won't solve it.
When we tried the next solution:
public async Task<object> Post([FromBody]string data)
{
// Save worker context:
var currentContext = HttpContext.Current;
object response = await Task<object>.Run( () =>
{
// Set the context of the current task :
HttpContext.Current = currentContext ; // Causes the calls not to work asynchronously for some reason!
// Executes logics for current request:
return ExecuteServerLogics(data);
});
return response;
}
for some reason, we noticed the performance got worse again, like it had returned working synchronously again.
Our problems are:
1. Why in the last example, setting the "HttpContext.Current" inside the await task,
causes the requests to return the same bad performance results which similar to the synchronous results?
2. Is there another way we can use "HttpContext.Current" inside the inner task that call - "ExecuteServerLogics",
and in all the static classes which also call "HttpContext.Current"?
am I doing the entire design wrong somehow?
Thanks!
From the beginning:
public async Task<object> Post([FromBody]string data)
{
object response = ExecuteServerLogics(data);
return response;
}
Don't ignore compiler warnings; the compiler will generate a warning for this method that specifically states it will run synchronously.
Moving on:
in some of the client's calls, we experienced performance issues.
Asynchronous code on the server will not be faster for a single call in isolation. It only helps you scale your server.
In particular, Task.Run will negate all the performance benefits of async and then degrade performance a bit beyond that. I believe the improvement in performance that you measured was coincidental.
in most posts we found that we should pass the worker thread's HttpContext reference into the inner Task that executes the server logics.
Those posts are wrong. IMHO. You end up using the HttpContext object from a background thread, when that object is specifically designed to be only accessed from a request thread.
am I doing the entire design wrong somehow?
I do recommend you take a step back and think about the big picture. When a request comes in, it has a certain amount of work to do. Whether that work is done synchronously or asynchronously is immaterial to the client; both approaches will take about the same amount of time.
If you need to return early to the client, then you'll need a completely different architecture. The usual approach is to queue the work to a reliable queue (e.g., Azure queue), have a separate backend (e.g., Azure WebRole), and proactively notify the client when the work is completed (e.g., SignalR).
That's not to say that async is useless, though. If ExecuteServerLogics is an I/O bound method, then it should be made asynchronous rather than blocking, and then you can use asynchronous methods as such:
public async Task<object> Post([FromBody]string data)
{
object response = await ExecuteServerLogicsAsync(data);
return response;
}
This will enable your server to be more responsive and scalable overall (i.e., not get overwhelmed by many requests).
If your task is inside your ApiController-derived class, you can use:
var ctx = this.Request.Properties["MS_HttpContext"] as System.Web.HttpContextWrapper;
This will give you an HttpContext wrapper with all the usual properties.
Amir I think you're looking for something like this below. I've been dealing with the same issue, trying to optimize a series of calls. It needs to be async all the way through, which means your ExecuteServerLogics() would need to be async, and you'd have to mark the containing lamda as async as well.
I believe following that pattern you can probably eliminate most of your performance issues. Nice passing the context through like that.
public async Task<object> Post([FromBody]string data)
{
// Save worker context:
var currentContext = HttpContext.Current;
object response = await Task<object>.Run(async () =>
{
// Set the context of the current task :
HttpContext.Current = currentContext ;
// Executes logics for current request:
return await ExecuteServerLogics(data);
});
return response;
}

Can I return a Task directly with HttpResponseMessage, such no async declaration is needed

I have the following WebAPI action and is wondering if returning Task<bool> and return _store.ContainerExistsAsync(container) directly is better;
I ask because, if I understand async/await correctly, the compiler creates a statemachine at the await to return to the same state. Returning the task directly without having to await it in the action, would that be theoretical faster?
public async Task<HttpResponseMessage> GetContainer(string container)
{
if (container.Length < 3 ||
container.Length > 63 ||
!Regex.IsMatch(container, #"^[a-z0-9]+(-[a-z0-9]+)*$"))
return Request.CreateResponse(HttpStatusCode.BadRequest, new { errors = new string[1] { "Container Name is not alowed." } })
return Request.CreateResponse<bool>(HttpStatusCode.OK, await _store.ContainerExistsAsync(container));
}
Yes, if you can implement an asynchronous method without async and await, then go ahead; async/await will add overhead.
This is commonly seen when the last line of a method has the only await and looks like return await ...;
In your particular example, I'm not 100% sure whether this would work since the method is doing something after the await.
It's easy enough to make it return the Task<bool> from ContainerExistsAsync directly, but the error handling would also need to change. If throwing a HttpResponseException works well enough, then yes, you would be able to implement an asynchronous method without using async.

Using "async" (even if it should complete) as part of a MVC route deadlocks the route; how can this be avoided?

Consider the following (based on the default MVC template), which is a simplified version of some "stuff" that happens in the background - it completes fine, and shows the expected result, 20:
public ActionResult Index()
{
var task = SlowDouble(10);
string result;
if (task.Wait(2000))
{
result = task.Result.ToString();
}
else
{
result = "timeout";
}
ViewBag.Message = result;
return View();
}
internal static Task<long> SlowDouble(long val)
{
TaskCompletionSource<long> result = new TaskCompletionSource<long>();
ThreadPool.QueueUserWorkItem(delegate
{
Thread.Sleep(50);
result.SetResult(val * 2);
});
return result.Task;
}
However, now if we add some async into the mix:
public static async Task<long> IndirectSlowDouble(long val)
{
long result = await SlowDouble(val);
return result;
}
and change the first line in the route to:
var task = IndirectSlowDouble(10);
then it does not work; it times out instead. If we add breakpoints, the return result; in the async method only happens after the route has already completed - basically, it looks like the system is unwilling to use any thread to resume the async operation until after the request has finished. Worse: if we had used .Wait() (or accessed .Result), then it will totally deadlock.
So: what is with that? The obvious workaround is "don't involve async", but that is not easy when consuming libraries etc. Ultimately, there is no functional difference between SlowDouble and IndirectSlowDouble (although there is obvious a structural difference).
Note: the exact same thing in a console / winform / etc will work fine.
It's to do with the way the synchronization context is implemented in ASP.NET (Pre .NET 4.5). There's tons of questions about this behavior:
Task.WaitAll hanging with multiple awaitable tasks in ASP.NET
Asp.net SynchronizationContext locks HttpApplication for async continuations?
In ASP.NET 4.5, there's a new implementation of the sync context that's described in this article.
http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime-targetframework.aspx
When you use .Result there is always a possibility of deadlock because .Result is blocking by nature. The way to avoid deadlocks is to not block on Tasks (you should use async and await all the way down). The subject is in details described here:
Don't Block on Async Code
One fix is to add ConfigureAwait:
public static async Task<long> IndirectSlowDouble(long val)
{
long result = await SlowDouble(val).ConfigureAwait(false);
return result;
}
Another fix is to use async/await throughout:
public async Task<ActionResult> Index()
{
var task = IndirectSlowDouble(10);
long result = await task;
ViewBag.Message = result.ToString();
return View();
}

Resources