Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand Tasks in .net

Tags:

c#

.net

asp.net

Ok I've been messing around with tasks in .net 4.5 and I'm trying to get my head around everything so I created a small app that does some work and I have a few questions about it.

Here is the code:

Account Controller.cs:

namespace MvcApplication1.Controllers
{
    public class AccountController : Controller
    {
        private readonly UserManager _manager;

        public AccountController()
        {
            _manager = new UserManager(ContextFactory.GetContext());
        }

    [HttpPost]
    public async Task<ActionResult> Register(LoginModel model)
    {
        var user = await _manager.FindAsync(model.UserName);
        if (user != null)
        {
            //do some work
        }
        else
        {
            ModelState.AddModelError("", "Cannot Find User");
            return View(model);
        }
    }
  }
}

User Manager.cs:

 namespace MvcApplication1
 {
   public class UserManager
   {
     private readonly IDBContext _context;

     public UserManager(IDBContext context)
     {
       _context = context;
     }
     public Task<UserProfile> FindAsync(string ID)
     {
       var queryHelper = new UserQueries(_context);
       var localID = ID;

        return Task.Factory.StartNew(() => queryHelper.GetProfile(localID));
      }
   }
 }

UserQueries.cs:

public class UserQueries
{
    private readonly IDBContext _context;
    public UserQueries(IDBContext context)
    {
        _context = context;
    }

    public UserProfile GetProfile(string ID){
        DataTable dt = _context.ExecuteDataTable(...)
        //do work with dt and return UserProfile
    }
  }
}

IDBContext.cs

public interface IDBContext
{
    DataTable ExecuteDataTable(string sql, IEnumerable<SqlParameter> parameters);
}

So I have a few questions here.

Do I have to create a new instance of the UserQuery class in every function? Not sure if it needs to be sync locked or not, still confused there.

Do I need to copy the ID to localID, I'm worried about scoping and reference changes when the function is called, is that even something to worry about in any case?

Should UserQueries be Task<UserProfile> as well?

If UserQueries should be Task<UserProfile> should the DBContext that returns a DataTable also be Task<DataTable>, does .net have a function for Taskable sql calls?

I'm not 100% sure how deep you go with Task

like image 886
dbarnes Avatar asked Dec 19 '13 15:12

dbarnes


People also ask

What is a task in C#?

Tasks in C# is nothing but an operation or a work that executes in asynchronous manner. It was introduced in.Net framework 4.0 to support asynchronous functionality, in-fact the Task Parallel Library which is known as TPL is based on the concept of Tasks. What is a Task in C# ?

What is a task in Java?

A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. Difference between Task And Thread This article describes the definition and uses of Task And Thread: What is Task? What is Thread? Why do we need Task? Why do we need Thread? What is Task in C#?

How to get the number of running tasks in a thread?

When you create a Task, by default the task is scheduled to run on a thread pool thread. So, you can get number of running tasks by using ThreadPool.GetMaxThreads and ThreadPool.GetAvailableThreads methods. Show activity on this post. Why would you want to find the list of running tasks?

Why do tasks run asynchronously on all threads?

Because tasks typically run asynchronously on a thread pool thread, the thread that creates and starts the task continues execution as soon as the task has been instantiated. In some cases, when the calling thread is the main application thread, the app may terminate before the task actually begins execution.


1 Answers

unless ExecuteDataTable has a Async version built in I would recommend against using Tasks. If you have to use Task.Factory.StartNew or Task.Run to make it work, you should likely not be doing it and you will get worse performance under load than you have gotten just leaving it synchronous.

Task.Run (and Task.Factory.StartNew) should only be used when you are waiting on a task that is CPU bound. ExecuteDataTable is a I/O operation, you are waiting for the database to respond, whatever API you are using to talk to the database may expose functions that return Task and those you could await on (and you would need to await all the way up your chain of calls to the first call) but if it does not expose a function that returns a Task you should just do it the normal way.

like image 74
Scott Chamberlain Avatar answered Oct 27 '22 00:10

Scott Chamberlain