数据层:using Dapper;
using ModelLayer;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace DataLayer
{
public class BookData
{
public async Task<IEnumerable<Book>> GetBooks1()
{
using (SqlConnection conn =new SqlConnection("xxxx"))
{
conn.Open();
return await conn.QueryAsync<Book>("select bookid,bookname,author from dbo.book",commandType:CommandType.Text);
//await异步执行
}
}
public Task<IEnumerable<Book>> GetBooks2()
{
using (SqlConnection conn = new SqlConnection("xxxx"))
{
conn.Open();
return conn.QueryAsync<Book>("select bookid,bookname,author from dbo.book", commandType: CommandType.Text);
//同步返回task
}
}
}
}逻辑层:using DataLayer;
using ModelLayer;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;namespace BusinessLayer
{
public class BookBussinessService
{
public async Task<IEnumerable<Book>> GetBooks1_1()
{
BookData dal = new BookData();
/*其他逻辑*/
return await dal.GetBooks1(); //await异步执行
}
public Task<IEnumerable<Book>> GetBooks1_2()
{
BookData dal = new BookData();
/*其他逻辑*/
return dal.GetBooks1();//同步返回task
}
public Task<IEnumerable<Book>> GetBooks2_1()
{
BookData dal = new BookData();
/*其他逻辑*/
return dal.GetBooks2();//同步返回task
}
}
}UI:using System.Collections.Generic;
using System.Threading.Tasks;
using BusinessLayer;
using Microsoft.AspNetCore.Mvc;
using ModelLayer;namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public async Task<IEnumerable<Book>> GetBooks1()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks1_1();
//view,业务层、数据层都是await执行,会(可能)要启动3个线程异步执行、等待。如果操作简单,线程交互会更耗时间。
}
public async Task<IEnumerable<Book>> GetBooks12()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks1_2();
//view,数据层都是await执行,业务层同步返回task.会(可能)要启动2个线程
}
public async Task<IEnumerable<Book>> GetBooks2()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks2_1();
//view是await执行,会(可能)要启动1个线程
}
}
}上面三类写法,特别是业务层的方法有哪些问题呢?用哪种比较好?
using ModelLayer;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace DataLayer
{
public class BookData
{
public async Task<IEnumerable<Book>> GetBooks1()
{
using (SqlConnection conn =new SqlConnection("xxxx"))
{
conn.Open();
return await conn.QueryAsync<Book>("select bookid,bookname,author from dbo.book",commandType:CommandType.Text);
//await异步执行
}
}
public Task<IEnumerable<Book>> GetBooks2()
{
using (SqlConnection conn = new SqlConnection("xxxx"))
{
conn.Open();
return conn.QueryAsync<Book>("select bookid,bookname,author from dbo.book", commandType: CommandType.Text);
//同步返回task
}
}
}
}逻辑层:using DataLayer;
using ModelLayer;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;namespace BusinessLayer
{
public class BookBussinessService
{
public async Task<IEnumerable<Book>> GetBooks1_1()
{
BookData dal = new BookData();
/*其他逻辑*/
return await dal.GetBooks1(); //await异步执行
}
public Task<IEnumerable<Book>> GetBooks1_2()
{
BookData dal = new BookData();
/*其他逻辑*/
return dal.GetBooks1();//同步返回task
}
public Task<IEnumerable<Book>> GetBooks2_1()
{
BookData dal = new BookData();
/*其他逻辑*/
return dal.GetBooks2();//同步返回task
}
}
}UI:using System.Collections.Generic;
using System.Threading.Tasks;
using BusinessLayer;
using Microsoft.AspNetCore.Mvc;
using ModelLayer;namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public async Task<IEnumerable<Book>> GetBooks1()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks1_1();
//view,业务层、数据层都是await执行,会(可能)要启动3个线程异步执行、等待。如果操作简单,线程交互会更耗时间。
}
public async Task<IEnumerable<Book>> GetBooks12()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks1_2();
//view,数据层都是await执行,业务层同步返回task.会(可能)要启动2个线程
}
public async Task<IEnumerable<Book>> GetBooks2()
{
BookBussinessService service = new BookBussinessService();
return await service.GetBooks2_1();
//view是await执行,会(可能)要启动1个线程
}
}
}上面三类写法,特别是业务层的方法有哪些问题呢?用哪种比较好?
哪个最好?你可以使用vs的脚手架创建一个mvc5的项目,看看里边是怎么用await async的,它就是微软推荐的方式。就是你的方式1
为什么呢?
因为同步和异步的混合编程,容易造成死锁。
http://www.knowsky.com/897585.html
async和await并不是简单的启动一个线程。你如果非要理解可以这样理解,在遇到await的时候系统就挂起当前的操作,等待async的返回,返回后继续执行,但是这些操作都被转换到一个线程里了。当然详情并不是这样。但是也不是你想的单纯的启动线程。
异步调用:执行方法并提供回调,执行下一指令(方法结束后通过回调处理结果)
async await 提供一个语法结构,允许你以同步调用的形式书写异步调用。await 修饰的是回调所以你的几种写法是一样的,何况三层间是有明确分工的,离开约束,将控制从一层的内部进入到另一层的内部,就不是三层,而是大杂烩了
//入口
public async Task<string> GetBooks3()
{
await A1();
return "abc";
} public Task A1()
{
return A2();
}
public Task A2()
{
return A3();
}
public Task A3()
{
var tk = Task.Run(() =>
{
Debugger.Log(0, "", "111111111 \r\n");
});
return A4();
}
public Task A4()
{
var tk= Task.Run(() =>
{
Debugger.Log(0, "", "222222222 \r\n");
});
return tk;
}1、上面的程序,A3、A4中的Task执行顺序是不固定的。也就是意味着:如果一个方法内,包含有两个Task,如果要求先后顺序,则必须都加await。
2、上面的:public Task<IEnumerable<Book>> GetBooks2()
{
using (SqlConnection conn = new SqlConnection("xxxx"))
{
conn.Open();
return conn.QueryAsync<Book>("select bookid,bookname,author from dbo.book", commandType: CommandType.Text);
//同步返回task
}
}在执行时因为是在UI中await的,在执行回调时,using的资源已经释放,会引发错误。
3、直接返回Task、与返回async Task 需要按照实际业务使用,只是直接返回Task的是同步而已。所以一般为了避免上面2种错误,可以都使用 async Task(即方法内都写await)。而是否开启异步线程则是不一定的(.net运行时会自动处理,怎么处理的原理不明白)。
所以你的两个问题其实都比较“轻”:
第一个,返回 Task 和 async/await 语法两种形式,其实本质上是一样的。返回 Task 则意味着调用方来决定是阻塞获取 result 还是使用 Task 的异步方法(包括调用方使用 wait 语法)来使用它。而定义为 async/await 语法则强迫所有调用这类方法的代码也必须写成 async/await 的i形式。只有这个区别。第二个,其实那你的业务逻辑层应该直接调用成熟的数据库引擎来操作数据库,既然已经有了多种成熟的 DAL 引擎框架直接用就好了,不要自己写什么 DAL 代码,尤其不要围绕着 BLL 类型来胡乱写什么 DAL 代码。