码迷,mamicode.com
首页 > Windows程序 > 详细

C#基础___异步编程

时间:2015-12-22 22:48:49      阅读:334      评论:0      收藏:0      [点我收藏+]

标签:

C#异步编程_0

三种常见模式:1.async/await    2.Background类    3.BeginInvoke/EndInvoke

一、async/await

代码示例:

技术分享
class Program
    {
        static void Main()
        {
            Task<int> value = DoAsyncStuff.Handing(5, 6);
        }
        
    }
    static class DoAsyncStuff
    {
        public static async Task<int> Handing(int i1, int i2)
        {
            int sum = await Task.Run(() => GetSum(i1, i2));
            return sum;
        }
        public static int GetSum(int i1, int i2)
        {
            return i1 + i2;
        }
    }
async/await示例代码

异步方法有3中返回类型 1.void  2.Task  3.Task<T>

1.如果返回类型为void控制流退出。

2.如果返回类型为Task后续部分将设置Task的属性并退出

3.如果返回类型为Task<T>,后续部分将设置Task对象的Result属性并退出。

异步方法的控制流如下图所示:

技术分享

await表达式:

await task ;     task为一个异步执行的任务,为Task类型的对象;task为一个awaitable类型的实例,可以使用Task类来构建awaitable类型;                                               

Task.Run(Func<TReturn> func);  //可构建awaitable类型;

Func<TReturn>为一个不含任何参数,返回类型为TReturn的预定义委托。

如下代码所示:

技术分享
 public int Get10()   //与Func<int>委托兼容
        {
            return 10;
        }
        public async Task DoWorkAsync()
        {
            Func<int> ten = new Func<int>(Get10);

            int a = await Task.Run(ten);
        }
await代码示例

取消一个异步操作

 

CancellationToken、CancellationTokenSource ;            //System.Threading.Tasks;

1.CancellationToken对象的任务需要定期检查其令牌(Token)的状态,如果其IsCancellationRequested属性为true,则操作停止并返回;

2.IsCancellationRequested属性设置为true后不可更改,类似一个开关程序;

3.CacellationTokenSource可调用Cancel方法,然后会将Cancellation的IsCancellationRequested属性设置为true;

技术分享
CancellationTokenSoruce cts=new CancellationTokenSoruce();
CancellationToken token=cts.Token;
CancellationToken代码示例

异步/同步等待任务完成

同步方法中等待任务完成:Task.WaitAll();  Task.WaitAny();

技术分享
Task<int>[] tasks=new Task<int>[]{t1,   t2  };
Task.WaitAll(tasks);
Task.WaitAny(tasks);
Wait代码示例

异步方法中等待任务完成:Task.WhenAll(); Task.WaitAny();

技术分享
List<Task<string>> tasks=new List<>(Task<string>);
tasks.Add(t1);
tasks.Add(t2);
await Task.WhenAll(tasks);
异步Wait示例代码

二、BackgroundWorker类

 BackgroundWorker类中主要用到的有这列属性、方法和事件:
    重要属性:
    1、CancellationPending               获取一个值,指示应用程序是否已请求取消后台操作。通过在DoWork事件中判断CancellationPending属性可以认定是否需要取消后台操作(也就是结束线程);
    2、IsBusy                                  获取一个值,指示 BackgroundWorker 是否正在运行异步操作。程序中使用IsBusy属性用来确定后台操作是否正在使用中;
    3、WorkerReportsProgress           获取或设置一个值,该值指示BackgroundWorker能否报告进度更新
    4、WorkerSupportsCancellation    获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。设置WorkerSupportsCancellation为true使得程序可以调用CancelAsync方法提交终止挂起的后台操作的请求;
    重要方法:
    1、CancelAsync                          请求取消挂起的后台操作
    2、RunWorkerAsync                    开始执行后台操作
    3、ReportProgress                      引发ProgressChanged事件  
    重要事件:
    1、DoWork                                调用 RunWorkerAsync 时发生
    2、ProgressChanged                   调用 ReportProgress 时发生
    3、RunWorkerCompleted             当后台操作已完成、被取消或引发异常时发生
    另外还有三个重要的参数是RunWorkerCompletedEventArgs以及DoWorkEventArgs、ProgressChangedEventArgs。

 

    技术分享

技术分享
 BackgroundWorker bkWorker = new BackgroundWorker();
 bkWorker.WorkerReportsProgress = true;
 bkWorker.WorkerSupportsCancellation = true;
 bkWorker.DoWork += new DoWorkEventHandler(DoWork);
 //bkWorker.ProgressChanged += new ProgressChangedEventHandler(ProgessChanged);
  bkWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWork);

public void DoWork(object sender, DoWorkEventArgs e)
        {
            CreatWord();
        }
 public void CompleteWork(object sender, RunWorkerCompletedEventArgs e)
        {
            Language.OfferLetterStatues = "报价书已完成!";
        }
 public void CreatWord()
         {
              //CreatWord.....
          }
BackgroundWorker示例代码

 三、BeginInvoke. EndInvoke方法

 技术分享 

如上所示为使用这一过程的三种标准模式。

1.当我们调用委托的BeginInvoke方法时,它开始在一个独立的线程执行引用方法,并且立即返回原始线程,原始线程可以继续,而引用方法会在线程池中的线程中并行执行。

2.当需要获取异步方法的结果时,可以检查BeginInvoke返回的IAsyncResult的IsCompleted属性,或调用委托的EndInvoke方法来等待委托完成。

BeginInvoke方法

技术分享
delegate int MyDel(int first ,int second);

    class MyClass
    {
        static int Sum(int x,int y)
        {
            return x + y;
        }
        MyDel del = new MyDel(Sum);
        IAsyncResult iar = del.BeginInvoke(2, 4, null, null);
    }
BeginInvoke示例代码

方法参数:1.引用方法需要的参数;2.两个额外的参数---CallBack参数和State参数;

返回类型:返回给调用线程一个实现IAsyncResult接口的对象引用,这个接口包含线程池中线程运行异步方法的当前状态。

EndInvoke方法

EndInvoke方法用来获取由异步方法调用返回的值,并且释放线程使用的资源。具体特效如下:

方法参数:BeginInvoke方法返回的IAsyncResult对象的引用

返回类型:引用方法的返回值并将其作为方法的返回值

工作原理:1.如果线程池的线程已经退出,EndInvoke做如下事情:清理退出线程的状态并且释放其资源。返回引用方法的返回值

              2.若果异步调用的线程仍在运行,调用线程就会停止并等待,直到清理完毕并返回值。

等待一直到完成模式(wait-until-done)

技术分享
delegate int MyDel(int first,int second);  
    class Program
    {
        static int Sum(int x,int y)
        {
            return x + y;
        }
        static void Main(string[] args)
        {
            MyDel del = new MyDel(Sum);
            IAsyncResult iar = del.BeginInvoke(3, 3, null, null); //开始异步调用
            //同步方法中的  DoSomething.....
            int result = del.EndInvoke(iar);  //等待结束并获取结果
        }
    }
等待到结束示例

轮询模式(Polling)

工作原理:在轮询模式中,原始线程发起了异步方法的调用,做一些其他处理,然后使用IAsyncResult对象的IsComplete属性来定期检查开启的线程是否完成,如果异步方法已经完成,就调用EndInvoke,否则,它做一些其他处理,然后过一会再来检查。

技术分享
delegate int MyDel(int first,int second);  
    class Program
    {
        static int Sum(int x,int y)
        {
            return x + y;
        }
        static void Main(string[] args)
        {
            MyDel del = new MyDel(Sum);
            IAsyncResult iar = del.BeginInvoke(3, 3, null, null); //开始异步调用
            while(!iar.IsCompleted)   //检查异步方法是否完成
            {
                Console.WriteLine("Not Done");
                //同步方法中的  DoSomething.....
            }
            Console.WriteLine("Done");
            int result = del.EndInvoke(iar);  //等待结束并获取结果
        }
    }
轮询模式示例代码

回调模式(CallBack)

工作原理:一旦初始线程发起了异步方法,它就自己管自己啦,不用再考虑同步方法,当异步方法调用结束之后,系统调用一个用户自定义的方法来处理结果,并且调用委托的EndInvoke方法,这个用户自定义的方法叫做回调方法

BeginInvoke的参数列表最后两个额外的参数由回调方法使用:

1.第一个参数callback,为回调方法的名字

2.第二个参数state,

回调方法:回调方法的参数和返回类型必须AsyncCallback委托类型形式一致,参数为IAsyncResult,返回类型为void;即 void AsyncCall(IAsyncResult iar);

回调方法内调用EndInvoke:在回调方法内,我们的代码应该调用委托的EndInvoke方法来处理异步方法执行后的输出值,需要调用委托的EndInvoke方法,我们肯定需要委托对象的引用,而委托在初始线程中,不在异步方法的线程中。

技术分享
delegate int MyDel(int first,int second);  
    class Program
    {
        static int Sum(int x,int y)
        {
            return x + y;
        }
        static void CallWhenDone(IAsyncResult iar)  //回调方法
        {
            AsyncResult ar = (AsyncResult)iar;
            MyDel del = (MyDel)ar.AsyncDelegate; //获取在其上调用异步调用的委托对象
            int result = del.EndInvoke(iar);
        }
        static void Main(string[] args)
        {
            MyDel del = new MyDel(Sum);
            IAsyncResult iar = del.BeginInvoke(3, 3, CallWhenDone, null); //开始异步调用
            while(!iar.IsCompleted)   //检查异步方法是否完成
            {
                Console.WriteLine("Not Done");
                //同步方法中的  DoSomething.....
            }
            Console.WriteLine("Done");
            int result = del.EndInvoke(iar);  //等待结束并获取结果
        }
    }
回调模式示例代码

AsyncResult类

MSDN详解:https://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.asyncresult.aspx

 

 

参考博客:C# BeginInvoke与EndInvoke的使用

               C#线程系列讲座(1):BeginInvoke和EndInvoke方法

                VS2005中BackgroundWorker组件的使用经验

 

C#基础___异步编程

标签:

原文地址:http://www.cnblogs.com/hdtechnology/p/4931677.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!