1

I've normal N tier simplified scenario below:

CONTROLLER calls BLL calls DAL

Where CONTROLLER has method below:

public void WarmUp()
{
    var bll=_bll.WarmUp(ID);
}

BLL has:

public bool WarmUp()
{
    return_dal.WarmUp(ID);
}

DAL has:

public bool FetchData()
{
    var dal=_bll.WarmUp(ID);
    if(dal !=null)
     {return true;}
    else{return false;}
}

Now, what I like to do is make the BLL and DAL methods (not sure if both has to be async) to be ASYNC such that after CONTROLLER invokes, it doesn't block the thread.

I've not done Task based programming yet. Could someone please help me convert the above code(BLL/DLL) to be async (c# async await) so that they are asynchronous?

3 Answers 3

3

Your DAL code calls into the BLL, which is wrong.

The DAL should be using database calls, and that's the point where you start. E.g. Entity Framework supports asynchronous APIs, which you call and then await. This makes your DAL methods async, so their callers (in the BLL) must await them. This makes your BLL methods async, so their callers (in the "controller") must await them. This makes your "controller" methods async.

Sign up to request clarification or add additional context in comments.

Comments

1

Generally we can say, that the first calling method should be marked with async. In your case this is the WarmUp Method in the Controller.

public async void WarmUp()
{
    var bll=_bll.WarmUp(ID);
}

Now we assume that _bll.WarUp(ID) is a long-running method. So we will refactor this method in such a way that it will return a Task

public Task<bool> WarmUp()
{
    return Task.Run(()=>{_dal.WarmUp(ID);});
}

But this will not solve our problem, because now we have the case that if we call the Controller method we will immediately return. This is no problem if we do not need the return vallue of Task. But if we need it we can use the await keyword:

public async void WarmUp()
{
    var bll= await _bll.WarmUp(ID);
    if(bll)
    {
        //do whatever you want
    }
}

2 Comments

You shouldn't use async void methods, unless you have to.
Yes, I know that async void is a fire and forget method, but I use it very often in MVVM when executing a ICommand.Execute. Maybe this is n't also the best solution?
-2

How about this:

public Task<bool> FetchData()
{
    var tcs = new TaskCompletionSource<bool>();
    Task.Run(() => {
        var dal=_bll.WarmUp(ID);    
        tcs.SetResult(dal != null);
    });

    return tcs.Task.Result;
}

TaskCompletionSource is good for making something not async to become async'able. Then you can just await the calls up until your last layer

public async Task<bool> WarmUp()
{
    return await _dal.WarmUp(ID);
}

This could be your GUI button callback. At some point you need an async void method, but this is a fire-and-forget-method. Should be avoided unless you've got an event handler of some kind.

public async void WarmUp()
{
    var bll= await _bll.WarmUp(ID);
}

4 Comments

This use of TaskCompletionSource doesn't make any sense. Yes, it makes the method awaitable, but it doesn't make it asynchronous. That means being able to await it is completely useless.
@svick You are right! I've updated my answer to make it async as well
Okay, if you use Task.Run(), why don't you just return that Task? It's simpler and handles exceptions correctly.
Alright alright, I agree TaskCompletionSource is not the thing for this case. You would use TaskCompletionSource if you called a method with a callback for instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.