[RESOLVED]Separation of Concerns – Async Method

Hi. I’m learning ASP.NET MVC, and one of the strengths of the design pattern is separation of concerns. So I decided to use Dependency Injection on the controller’s methods:

I’ve been able to have an interface that works with CRUD operations on the database. The thing is that originally, the controller had async capabilities, and now, since the code is being executed on another class different from the controller I get the note

"This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to wait non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Let me explain:

I have this two methods:

  public async Task<ActionResult> Index()
        {
            
            return View(ClientProcess.ListClients(dbs, sid));
        }

        // GET: Clients/Details/5
        public async Task<ActionResult> Details(int? id)
        {
           if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Client client = ClientProcess.DetailsClient(dbs,id,sid);
                if (client == null)
                {
                    return HttpNotFound();
                }
                return View(client);
        }

And using Dependency injection on the same controller:

private IClient ClientProcess;
private IDbRepositories dbs;
private IIntegrity check;

       public ClientsController(IClient client_, IDbRepositories db_, IIntegrity check_)
        {
            ClientProcess = client_;
            dbs = db_;
            check = check_;
        }

And then, my IoC container works to inject the following code:

 public class clsClientProcessor : IClient
    {
      public IEnumerable<Client> ListClients(IDbRepositories dbs, int uid)
        {
            //Select the Client from the Database and verify that it's active and it's from the user requesting it.
            var query = from c in dbs.ClientsDB where c.IboID == uid && c.status == 1  select c;
            return query;
        }

        public void AddClient(IDbRepositories dbs, Client client, int uid)
        {
          {
              //Set the client's IBO ID field with the current user.
              client.IboID = uid;
              //Set the client's status to 1 to mark it as activated.
              client.status = 1;
              //Add it to the Clients table.
              dbs.DB.Clients.Add(client);
              //Save Changes to the Database
              dbs.DB.SaveChanges();
           }
        }
        public void RemoveClient(IDbRepositories dbs, Client client)
        {
            //Set the client's status to 0 to mark it as deactivated or removed.
            client.status = 0;
            //Update the client using the EditClient method.
            EditClient(dbs, client);
        }
        public void EditClient(IDbRepositories dbs, Client client)
        {
            //Verify integrity
            dbs.DB.Entry(client).State = EntityState.Modified;
            //Save the changes
            dbs.DB.SaveChanges();
        }
        public Client DetailsClient(IDbRepositories dbs, int? id, int uid)
        {
            Client client = dbs.ClientsDB.SingleOrDefault(c => (c.IboID == uid) && (c.ID == id) && (c.status == 1));
            return client;
        }
    }

Since I have  many void methods, I’d like to know what should I do so I can run them asynchronously and maintain the separation of concerns?

Thanks :D

Hi superjose,

According to your description, I would like to know is it just the warning message.

superjose

Since I have  many void methods, I’d like to know what should I do so I can run them asynchronously and maintain the separation of concerns?

Base on your code, you don’t have the asynchronous method. For the asynchronous method, please refer to this code below:

  public async void EditClient(IDbRepositories dbs, Client client)
        {
            //Verify integrity
            dbs.DB.Entry(client).State = EntityState.Modified;
            //Save the changes
            dbs.DB.SaveChanges();
        }
 public async Task<Client> DetailsClient(IDbRepositories dbs, int? id, int uid)
        {
            Client client = dbs.ClientsDB.SingleOrDefault(c => (c.IboID == uid) && (c.ID == id) && (c.status == 1));
            return client;
        }
 public async Task<ActionResult> Details(int? id)
        {
           if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                Client client = await ClientProcess.DetailsClient(dbs,id,sid);
                if (client == null)
                {
                    return HttpNotFound();
                }
                return View(client);
        }

Best Regards

Starain

Wooohooooooo!!!!! :D

Thanks!!!!! :D :D :D. That worked!

unless you are going to call two methods async from the controller, there is no benefit and actually a performance cost, in calling sync processes async.

a true async process executes on the same thread, and fires a completion event. this allows asp.net to return the thread to the pool to do other work while waiting for the async process to complete. but if you just create a async wrapper, you are just creating
a new thread (thus pulling a thread from the pool) to run the sync process. and now you are adding all the synchronization code processing. 

Ok. I was just adapting it from what the template created, and from what I read in here:

http://hanselminutes.com/327/everything-net-programmers-know-about-asynchronous-programming-is-wrong

Anytime  that  your  server  side  ASP.NET  code  is making  a database  call,  or  a  web  service call  or  a network call or talking to the file system, that can be done asynchronously such that while that operation is in progress ASP.NET doesn’t
have to be consuming a thread which is a CPU resource on that box while that operation is taking place.

Leave a Reply