.NET通过async/await实现并行

如果可以并行可以大大提高性能,但在我们的使用中,不可能全是并行的也是要有线行操作,所以我们需要在业务逻辑层进行并行操作的护展:

数据访问层不变还是以前一样如下:

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毫秒左右


C#异步编程再续 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

怎么了,看了上面的例如,是否是对并行编程有了新的认识呢!线程


C# 同步转异步 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;
    }

测试效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/WuLex/article/details/116724029