如何使C#方法异步

时间:2013-11-26 11:50:10

标签: c# asynchronous async-await c#-5.0

下面是正常的N层简化方案:

CONTROLLER调用BLL调用DAL

其中 CONTROLLER有以下方法:

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

BLL有:

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

DAL:

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

现在,我喜欢做的是使BLL和DAL方法(不确定两者都必须 async )是ASYNC,这样在CONTROLLER调用之后,它不会阻塞线程

我还没有完成基于任务的编程。有人可以帮我转换上面的代码(BLL / DLL)为异步(c#async等待),以便它们是异步的吗?

3 个答案:

答案 0 :(得分:3)

您的DAL代码调用BLL,这是错误的。

DAL应该使用数据库调用,这就是你开始的地方。例如。实体框架支持您调用的异步API,然后await。这使得您的DAL方法async,因此他们的调用者(在BLL中)必须await他们。这使得您的BLL方法async,因此他们的调用者(在“控制器”中)必须await他们。这使您的“控制器”方法async

答案 1 :(得分:1)

通常我们可以说,第一个调用方法应该用async标记。在您的情况下,这是Controller中的WarmUp方法。

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

现在我们假设_bll.WarUp(ID)是一个长期运行的方法。因此,我们将重构此方法,使其返回Task

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

但是这不会解决我们的问题,因为现在我们有这样的情况:如果我们调用Controller方法,我们将立即返回。如果我们不需要Task的返回值,这没有问题。但如果我们需要,我们可以使用await关键字:

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

答案 2 :(得分:-2)

这个怎么样:

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有助于使非异步变得异步。然后你可以等到最后一层的电话

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

这可能是您的GUI按钮回调。在某些时候,您需要一个异步void方法,但这是一种即发即弃的方法。应该避免,除非你有某种事件处理程序。

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