你的位置:首页 > 软件开发 > ASP.net > .NET中的异步编程

.NET中的异步编程

发布时间:2016-03-11 23:00:18
开篇异步编程是程序设计的重点也是难点,还记得在刚开始接触.net的时候,看的是一本c#的Winform实例教程,上面大部分都是教我们如何使用Winform的控件以及操作数据库的实例,那时候做的基本都是数据库的demo,数据量也不大,程序在执行的时候基本上不会出现阻塞的情况。随着不 ...

.NET中的异步编程

开篇

异步编程是程序设计的重点也是难点,还记得在刚开始接触.net的时候,看的是一本c#的Winform实例教程,上面大部分都是教我们如何使用Winform的控件以及操作数据库的实例,那时候做的基本都是数据库的demo,数据量也不大,程序在执行的时候基本上不会出现阻塞的情况。随着不断的深入.net,也开始进入的实战,在实际的项目,数据量往往都是比较大,特别是在大量的数据入库以及查询数据并进行计算的时候,程序的UI界面往往卡死在那里,发生了阻塞,这时候就需要对计算时间限制的过程进行异步处理,让UIget='_blank'>线程继续相应用户的操作,使得用户体验表现比较友好,同时正确的使用异步编程去处理计算限制的操作和耗时IO操作还能提升的应用程序的吞吐量及性能。由此可见,异步编程的重要性。

 程序定义了一个DoWork类型无参无返回值的的委托类型,no.1用WorkPro方法实例化一个DoWork类型的对象d ,no.2通过委托对象dBeginInvoke(null,null)(下面将会详细介绍BeginInvoke函数中两个参数如何使用)来实现WorkPro函数的异步调用,这样就使得no.3主线程所做的for循环和WorkPro函数可以同时执行,这样使得程序的运行效率得到了大幅度的提升。如果程序是同步执行的话,假设WorkPro函数执行需要2秒,for需要1秒,总共执行时间就需要3秒,如果WorkPro是异步执行的话,那么整个程序执行完毕只需要2秒就够了。我们已经把委托类型改为具有一个int类型的参数和int类型返回值。在这里解释一下,每当你的编译器发现定义了一个委托类型,就会对应的生成一个类型,并且该类型BeginInvoke方法的参数个数也是不同的,本例声明的委托类型为:首先来解释一下BeginInvoke方法的第二个参数是AsyncCallBack 类型的委托(回调函数),当该参数不为空,那么在异步函数执行完毕之后,会调用该委托;第三个参数Object 类型的,代表传递给回调函数的异步调用状态。CallBack回调函数必须带有一个IAsyncResult 类型的参数,通过这个参数可以在回调方法内部获取异步调用的结果。在no.1出就给BeginInvoke函数传递了回调函数CallBack,和委托d,当异步数WorkPro执行完毕之后,就立即通知CallBack回调函数来显示执行结果。这下主线程就不需要阻塞一直的等待异步函数的结果,大大的提升了程序的运行效率。在.net还提供许多类的BeinXXX()EndXXX()的异步版本,比如文件的读写等,具体可以查阅相关的资料。2)public Thread( ParameterizedThreadStart start ):其中ParameterizedThreadStart 是一个带有一个Object类型的参数,无返回值的委托类型。其中,当异步函数中处理需要多个参数时,那么只需要建立一个参数类,参数类中包括你函数需要的参数个数,然后将这个参数类传递给异步函数即可。no.1处使用Task的构造函数为:--------如果任务中出现了异常,那么异常会被吞噬掉,并存储到一个集合中去,而线程可以返回到线程池中去。但是如果在代码中调用了Wait方法或者是Result属性,任务有异常发生就会被引发,不会被吞噬掉。其中Result属性内部本身也调用了Wati方法。Wait方法和上一节中的委托的EndInvoke方法类似,会使得调用线程阻塞直到异步任务完成。下面我们会介绍如何避免获取异步结果的阻塞情况,在讲解之前,先说一下,如何取消正在运行的任务。  

.NET中的异步编程

代码如下。
 public partial class Form1 : Form  {    private readonly TaskScheduler contextTaskScheduler;//声明一个任务调度器    public Form1()    {      InitializeComponent();      contextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();//no.1获得一个上下文任务调度器    }     private void button1_Click(object sender, EventArgs e)    {      Task<int> t = new Task<int>((n) => Sum((int)n),100);      t.Start();      t.ContinueWith(task =>this.textBox1 .Text =task.Result.ToString(),contextTaskScheduler);//当任务执行完之后执行      t.ContinueWith(task=>MessageBox .Show ("任务出现异常"),CancellationToken.None ,TaskContinuationOptions.OnlyOnFaulted,contextTaskScheduler );//当任务出现异常时才执行    }    int Sum(int count)    {      int sum = 0;      for (int i = 0; i < count; i++)      {        Thread.Sleep(10);        sum += i;      }      Console.WriteLine("任务处理完成");      return sum;    }  }
在no.1窗体的构造函数获取该UI线程的同步上下文调度器。在按钮的事件接受异步执行的结果时候,都传递了contextTaskScheduler同步上下文的调度器,目的是,当异步任务完成之后,调度UI线程去执行任务完成之后的回调函数。

原标题:.NET中的异步编程

关键词:.NET

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。