如果可以并行可以大大提高性能,但在我们的使用中,不可能全是并行的也是要有线行操作,所以我们需要在业务逻辑层进行并行操作的护展:
数据访问层不变还是以前一样如下:
public class UserDAL
{
public User GetUser()
{
User user = new User();
user.Name = "N1";
user.Address = "A1";
return user;
}
public List<User> GetUserList()
{
List<User> list = new List<User>();
list.Add(new User { Name = "N11", Address = "A11" });
list.Add(new User { Name = "N12", Address = "A12" });
return list;
}
}
业务逻辑层需要护展有async,如下:
public class UserBLL
{
UserDAL dal = new UserDAL();
public async Task<User> GetUserAsync()
{
return await Task.Run(() => { return dal.GetUser(); });
}
public User GetUser()
{
return dal.GetUser();
}
public async Task<List<User>> GetUserListAsync()
{
return await Task.Run(() => { return dal.GetUserList(); });
}
public List<User> GetUserList()
{
return dal.GetUserList();
}
}
最后是调用了,如下:
UserBLL userBLL = new UserBLL();
public async Task<ActionResult> Index()
{
var user = userBLL.GetUserAsync();
var listUser = userBLL.GetUserListAsync();
int t1 = Environment.TickCount;
await Task.WhenAll(user, listUser);
ViewBag.User = user.Result;
ViewBag.ListUser = listUser.Result;
//ViewBag.User = await user;
//ViewBag.ListUser = await listUser;
ViewBag.Times = Environment.TickCount - t1;
return View();
}
具体的性能我们可以测试,在数据访问层每次延时500毫秒,用并行和线行测试一下,并行大约时间在500毫秒左右,而线行则在1000毫秒左右
async
异步方法与同步方法的并行今天晚上没事写了个测试的代码,又看了看.net的并行编程,两个方法,一个是异步async
修饰的,另外一个是普通的方法,在控制台程序的Main
方法里去调用这两个方法,会有什么结果呢?编程
首先咱们看一下方法的组成,step1以下异步
public async void Step1()
{
try
{
//await进行等待后,新线程的异常能够被主线程捕捉,这是正常的,下面的代码不会被执行
await Task.Run(() =>
{
Console.WriteLine("Step1 Current ThreadID" + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(3000);
});
await Task.Run(() =>
{
Console.WriteLine("Step1 Current ThreadID" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("ThreadTest.Test Runing");
});
}
catch (Exception ex)
{
Console.WriteLine("ThreadTest" + ex.Message);
}
}
step2以下async
public void Step2()
{
Console.WriteLine("Step2 Current ThreadID" + Thread.CurrentThread.ManagedThreadId);
}
咱们能够看到step2很简单,不会有什么延时,就是在屏幕上输出一段话,而step1就显得复杂一些了,它是一个异步的方法,而且使用Task.Run
开启了两个新线程,而第一测试
个线程的运行时间是3秒,很长呀,哈哈,第二个是在屏幕上输出一段话!如今咱们把step1和step2写在一块儿会出现什么状况呢?spa
var test = new ThreadTest();
test.Step1();//整个方法不阻塞,但方法内部有可能阻塞
test.Step2();
经过上面的图咱们认识到了,step1按着顺序先执行,而因为第一个线程要执行3秒,这时step2被并行执行,3秒后,step1的第二个线程继续执行(因为使用了await
,因此step1内部进行了等待,不会应响他外面的方法,也应响不了,呵呵!.net
怎么了,看了上面的例如,是否是对并行编程有了新的认识呢!线程
TaskCompletionSource
当我们遇到一些异步执行又无法等待时的逻辑,比如动画的执行。
而业务上又需要等待逻辑的完成,再去处理后续的操作。这时需要转成异步方法
如下,同步执行一个动画后,再输出日志:
private async void TaskCompleteSourceAwait_OnClick(object sender, RoutedEventArgs e)
{
bool isCompleted = await AwaitByTaskCompletionAsync(new Storyboard() { Duration = new Duration(TimeSpan.FromSeconds(2)) });
Debug.WriteLine($"TaskCompleteSourceAwait_OnClick end:{isCompleted}");
}
通过TaskCompletionSource
如何转化为异步方法,并等待动画完成?
/// <summary>
/// 执行动画
/// </summary>
/// <param name="storyboard"></param>
/// <returns></returns>
public static async Task<bool> AwaitByTaskCompletionAsync(Storyboard storyboard)
{
var taskCompletionSource = new TaskCompletionSource<bool>();
Debug.WriteLine("Storyboard start");
storyboard.Completed += OnStoryboardCompleted;
storyboard.Begin();
void OnStoryboardCompleted(object sender, EventArgs e)
{
Debug.WriteLine("Storyboard end");
storyboard.Completed -= OnStoryboardCompleted;
taskCompletionSource.SetResult(true);
}
return await taskCompletionSource.Task;
}
测试效果:
阅读量:2008
点赞量:0
收藏量:0