下面是正常的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等待),以便它们是异步的吗?
答案 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);
}