Asncと待つと言って前に、まず、タスクタスク使用量ベースのFuncデリゲートとアクションを説明
1.のFunc
FUNCは、我々は、例えば、効率を向上させることができるデリゲートを使用して、System.Core名前空間に配置使用デリゲート、FUNCを委託されている新しい3.5、2.0内にある手数料、である、反射で反射の損失を補うことができパフォーマンス。
アクション<T>とのFunc <T、TResult>機能は同じですが、アクション<T>タイプを返さない、
のFunc <T、T、結果>は:パラメータがある、それはのタイプを返す
アクション、そしてどちらもリターンもパラメータを、
のFunc <T、TResult>
以下に分け症状:
1。FUNC <T、TResult>
2。FUNC <T、Tlの、TResult>
。3。FUNC <T、Tlの、T2、TResult>
。4。FUNC <T、Tlの、T2、T3、TResult>
。5。FUNC <T、T1、T2、 T3、T4、TResult>
それぞれ、各パラメータの意味は、前記TResultを示す
パラメータ型デリゲートは、Tを表し、T1、T2、T3の値を返し 、T4の表現デリゲートが呼び出さタイプは、
以下の例が使用されます。
1のFunc <int型、ブール> myFuncという = NULL; // すべての変数は 2 3 = X = myFuncという> CheckIsInt32(X); 4ラムダ式を使用してローカルデリゲート//パッケージング方法に関する 。5 。6プライベートBOOL CheckIsInt32(ParsでのINT) //カプセル化方法 7 { 8 == Parsでを返す5;。。 。9} 10 11 BOOL myFuncというOK =。(5); //委任するために呼び出します
MSDN:http://msdn.microsoft.com/zh-cn/library/bb534303(VS.95).aspx
2.アクション
しかし、我々はそれを行うには、それが増加、値のパッケージを返さないメソッドが必要な場合は?アクションの使用に!
あなたは使用することができます
アクション<T1、T2、T3、 T4> の代わりに明示的に宣言されたカスタムデリゲートのパラメータとしてデリゲート送信方法を。パッケージングの方法は、このメソッドシグネチャデリゲートに対応する定義されなければなりません。つまり、パッケージの方法は、次の4つのパラメータがそれに値が渡されている必要があり、その値を返すことができません。(C#では、メソッドはvoidを返す必要があります。Visual Basicでは、それはサブ... End Subの構造によって定義されている必要があります。)一般的に、この方法は、アクションを実行するために使用されます。
同様の使用とのFunc!
処置:リターンもパラメータもない、次のように使用:
1つのアクションACTION = NULL;処置の//定義 2 。3 ACTION = CheckIsVoid; //名前包装方法は、この方法は、必要にのみ 4。 5アクション(); //呼び出しを
MSDN:http://msdn.microsoft.com/zh-cn/library/bb548654(VS.95).aspx
要約:
使用のFunc <T、TResult>とアクション<T>、コードを簡素化するための委任を使用せずにアクションが実際に同じ効果を達成するために以下のコードを使用して、我々は、文のデリゲートを表示する必要はありません。
Func <T、TResult>最後のパラメータは、常に型を返すされ、そしてアクションは<T>ノーリターンの種類、ノーアクション入力パラメータや戻り値の型です。
3.タスク
非同期プログラミングの非同期と待つ使用(MSDNで良い記事): https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120)
タスク基本的な使用: C#のスレッドの知識-タスクの実行非同期操作を使用して
タスク結合および戻り値を待って、参照: .NET(C#)は:タスク待ちの方法は、非同期を返します
タスク深い理解は、以下を参照してください C#タスクの使用を
要約:タスクは、スレッドの使用の効果に、新しい、同様のマルチタスク、マルチスレッドの使用を提供していますが、分布は基本的なスレッド.NETによって制御されているか、その優れた性能は、高い効率は、我々は唯一の一方で、ビジネスロジックに集中する必要がありますスレッドで関数の戻り値が利用可能(コールバックイベントによって処理することができます)、およびタスクに簡単に使用中のawaitを使用していない前に、タスクがタスクの同期を呼び出すのと同じですが、戻り値があるでしょうが、書面で待ちます非同期、タスク、FUNC、アクションとそのキーワードに、初心者が混乱する可能性を使用して注意を要する分野、次の例では、コメントに新しい誰かの例を使用して、簡単な作業です!
。ボイド静的メイン1(文字列[]引数) 2 { 。使用してタスクを実行することができる3 //非同期メソッドは、そうでない場合のように、同期実行非同期タスクを待つ 。)(4試験; //出力5を第2に、タスクに非同期タスクに、以下現在のスレッド同期コードの実行に 6ログ(「メイン:テストを呼び出した後」); 7のThread.sleep(Timeout.Infinite); 8} 9 10 //メインメソッドは非同期を追加しないので、我々はのawaitでこの方法を使用します 。静的ボイドテスト非同期11() 12は{ 13は、第1の出力//、まだ入力されていないタスクである 。:14ログ(「のawait前試験」) 15 //タスクが目標斗の後に追加される待つコンテンツ後、及び別のタスクが実行されるテストは直ちに戻り、斗が入っている 16ログ(「タスクのDOO結果:」+ DOOを待つ()); 17 //タスクは上記の完了を待つ実行するために、現在のコードの実行が終了するまで待機します 18ログ(「試験:後待つ」); 19} 20は、タスクが非同期メソッド、メソッドは、値を返すタスクを有する標準的な非同期タスクを戻す//であります 非同期静的タスク21 <整数>ドゥー()である 22 {あります 23は非同期のawait非同期メソッドを使用して、簡単に説明すると//では、タスクのタスクが次々に実行される、同期方法タスクのタスクで実行される。 図24は、((= Task.Runするvar RES1を待ちます)=> {のThread.sleep(1000) ;( "待ちタスク1ログ実行");リターン1;}); ザが待つ25のvar RES2 Task.Run =(()=> {のThread.sleep(1000); "(ログTask2の実行を待つ"); 2を返す;}); 26のawait Task.Runするvar RES3 =(()=> {のThread.sleep(1000)である(ログ"待ちタスク3の実行「);戻り3;}); 27 28 //使用しないで待つ:マルチスレッドスレッドプールを、従って現在のタスクは、それがのawaitないので、実行されず、スレッド開いた _ =>(29 ThreadPool.QueueUserWorkItemを 30 { 31のThread.sleep(1000)であり、 32ログ( "ThreadPool.QueueUserWorkItem:マルチスレッド実行スレッドプール"); 33}); 34 35 //は使用しないで待っています:、現在のタスクとしてタスクマルチスレッドは、待っていないので、実行されませんが、タスクまで開いていた 36のタスクを。ラン(()=> 37 { 38のThread.sleep(1000); 39ログ(「Task.Run:タスク、マルチスレッド実行を"); 40 41)}であり、 42は、 図43は、RES1 RES2 + + RES3を返すあり; } 44である 45 //出力方法は:現在のスレッドの数と出力情報を表示 46である静的ボイドログ(文字列MSG) 47 { 48 Console.WriteLineを("スレッド{ } 0 {} 1」、Thread.CurrentThread.ManagedThreadId、MSG); 49}
次のように実行結果は以下のとおりです。
4.非同期、待ちます
これは最低限の.NETバージョン4.5を必要とし、.NET 4.5の特徴です。
基本的には非同期プログラミングのための任意の使用非同期、待つが表示されていない、友人の多くは、まだ非同期マルチスレッド操作の使用にスレッドを使用して参照してください。すべてが実際にすることができ、それを愛しています。限りラインの適切な使用として、それでも私はこの記事を書いた非同期、待つの使用をお勧めします。その理由はこれです:あなたは非同期プログラミングへの同期方法のように書くことができます。コードは非常に明確である、ちょうど非同期プログラミングの関係を行う方法のように、一般的なコードを書くだけでなく、ジュニアプログラマの多くは、非同期プログラムすることができます。ここでは、非同期スレッドのマルチスレッドを使用した例、および非同期の例非同期で、利用をお待ちしており、我々は単に非同期と待つの下で、関連する技術的な注意事項を理解します。
マルチスレッドの非同期プログラミング例スレッド
Programクラス { 静的な無効メイン(文字列[] args) { Console.WriteLineを( "テストのメインスレッド開始.."); スレッド新しい新TH =スレッド(ThMethod); th.Start(); のThread.sleep(1000); コンソール.WriteLine( "試験の主糸端.."); Console.ReadLine(); } 静的ボイドThMethod() { Console.WriteLineを( "非同期実行開始"); (; Iは<5; I ++はI = 0の整数)のための { Console.WriteLineを( "非同期実行" i.ToString +()+ ".."); のThread.sleep(1000); } Console.WriteLineを( "完全非同期実行"); } }
コードは、次の図に実行されます
非同期プログラミングを使用して非同期と待ちます
。静的ボイドメイン1(文字列[]引数) 2 { 3 Console.WriteLineを( "テストのメインスレッド開始..");。 。4 AsyncMethod(); 5のThread.sleep(1000); 。試験の6 Console.WriteLineを(「メインスレッドの終了.. "); 7 Console.ReadLine(); 8} 9。 10静的ボイドは、(非同期をAsyncMethod) 11 { 12 Console.WriteLineを(ある"非同期「コードを開始); 13のawaitのMyMethodはするvar結果=(IS); 14 Console.WriteLineを( "非同期コードが終了した" + result.ToStringは()); 15} 16 17は、タスク<整数> MyMethodは()非同期スタティック 18が{である 。私は<5; 19(I = 0 int型。私は++) 20は{ 21はConsole.WriteLineを(あります"非同期実行" + i.ToString()+ ".. "); //アナログかかる操作を、22 Task.Delay(1000)を待ちます 23} 24リターン100。 25}
業績:
明白な私達はちょうど同じ同期方法を記述し、非同期メソッド、コード明確の準備を完了しました。
唯一のキーワード内部待つ非同期を使用する必要があります。非同期メソッドは、タスク、タスク<>または無効戻り値の型を有していてもよいです。
キーワードは、戻り値が「待機中」されて待機するために使用されているタイプ(awaitable)メソッド
Asncと待つと言って前に、まず、タスクタスク使用量ベースのFuncデリゲートとアクションを説明
1.のFunc
Func是一种委托,这是在3.5里面新增的,2.0里面我们使用委托是用Delegate,Func位于System.Core命名空间下,使用委托可以提升效率,例如在反射中使用就可以弥补反射所损失的性能。
Action<T>和Func<T,TResult>的功能是一样的,只是Action<T>没有返类型,
Func<T,T,Result>:有参数,有返回类型
Action,则既没有返回也没有参数,
Func<T,TResult>
的表现形式分为以下几种:
1。Func<T,TResult>
2。Func<T,T1,TResult>
3。Func<T,T1,T2,TResult>
4。Func<T,T1,T2,T3,TResult>
5。Func<T,T1,T2,T3,T4,TResult>
分别说一下各个参数的意义,TResult表示
委托所返回值 所代表的类型, T,T1,T2,T3,T4表示委托所调用的方法的参数类型,
以下是使用示例:
1 Func<int, bool> myFunc = null;//全部变量 2 3 myFunc = x => CheckIsInt32(x); 4 //给委托封装方法的地方 使用了Lambda表达式 5 6 private bool CheckIsInt32(int pars)//被封装的方法 7 { 8 return pars == 5; 9 } 10 11 bool ok = myFunc(5);//调用委托
MSDN:http://msdn.microsoft.com/zh-cn/library/bb534303(VS.95).aspx
2. Action
但是如果我们需要所封装的方法不返回值,增么办呢?就使用Action!
可以使用
Action<T1, T2, T3, T4>委托以参数形式传递方法,而不用显式声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有四个均通过值传递给它的参数,并且不能返回值。(在 C# 中,该方法必须返回 void。在 Visual Basic 中,必须通过 Sub…End Sub 结构来定义它。)通常,这种方法用于执行某个操作。
使用方法和Func类似!
Action:既没有返回,也没有参数,使用方式如下:
1 Action action = null;//定义action 2 3 action = CheckIsVoid;//封装方法,只需要方法的名字 4 5 action();//调用
MSDN:http://msdn.microsoft.com/zh-cn/library/bb548654(VS.95).aspx
总结:
使用Func<T,TResult>和Action<T>,Action而不使用Delegate其实都是为了简化代码,使用更少的代码达到相同的效果,不需要我们显示的声明一个委托。
Func<T,TResult>的最后一个参数始终是返回类型,而Action<T>是没有返回类型的,而Action是没有返回类型和参数输入的.
3. Task
使用 Async 和 Await 的异步编程(msdn的好文章) : https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120)
Task基本使用: C# 线程知识--使用Task执行异步操作
Task和await结合返回值见: .NET(C#):await返回Task的async方法
Task深入了解见: C# Task的使用
总结: Task提供一种新的类似多线程的多任务的用法, 达到使用线程的效果,但具体怎么分配线程由.net底层控制,这样性能好,效率也高,我们只需要专注业务逻辑, 同时具备以前线程不具备的返回值的功能(可以通过回调事件来处理),而在Task中只是简单的使用await来使用, await的task相当于同步的调用task, 同时会有返回值,只是在书写方面需要注意async, task,func, action等等关键字的使用,新手可能很困惑, 下面的例子就是一个简单的task使用例子,新手注意注释!!!
1 static void Main(string[] args) 2 { 3 //异步方法, 当中使用await可以执行task异步任务,否则当作同步执行 4 test(); 5 //其次输出,因为异步进入task任务了,就同步执行当前线程下面的代码 6 log("Main:调用test后"); 7 Thread.Sleep(Timeout.Infinite); 8 } 9 10 //Main方法不允许加async,所以我们用这个方法使用await 11 static async void test() 12 { 13 //最先输出,还没有进入task 14 log("test: await之前"); 15 // await后的内容会被加在目标doo的Task的后面,然后test马上返回,而doo则是进入了另一个任务执行了 16 log("doo的Task的结果: " + await doo()); 17 // 会等到上面await执行的任务完成后才会执行当前代码 18 log("test: await之后"); 19 } 20 //返回Task的async方法, 一个标准的带返回值的异步task任务方法 21 static async Task<int> doo() 22 { 23 // 简单的说, async中使用await就是异步中以同步方式执行Task任务的方法,task任务一个接一个执行. 24 var res1 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task1 执行"); return 1; }); 25 var res2 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task2 执行"); return 2; }); 26 var res3 = await Task.Run(() => { Thread.Sleep(1000); log("Awaited Task3 执行"); return 3; }); 27 28 //不使用await:线程池多线程, 当前task不会等这个执行完,因为不是await,只是又开启了一个线程 29 ThreadPool.QueueUserWorkItem(_ => 30 { 31 Thread.Sleep(1000); 32 log("ThreadPool.QueueUserWorkItem: 线程池多线程执行"); 33 }); 34 35 //不使用await:Task多线程, 当前task不会等这个执行完,因为不是await,只是又开启了一个任务 36 Task.Run(() => 37 { 38 Thread.Sleep(1000); 39 log("Task.Run: Task多线程执行"); 40 41 }); 42 43 return res1 + res2 + res3; 44 } 45 //输出方法:显示当前线程号和输出信息 46 static void log(string msg) 47 { 48 Console.WriteLine("线程{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg); 49 }
执行结果如下:
4. Async、Await
这个是.NET 4.5的特性,所以要求最低.NET版本为4.5。
看很多朋友还是使用的Thread来使用异步多线程操作,基本上看不见有使用Async、Await进行异步编程的。各有所爱吧,其实都可以。只要正确使用就行,不过还是写了这篇文章推荐大家使用Async、Await。 原因就是:可以跟写同步方法一样去异步编程。代码则就非常的清晰,就跟写普通的代码一样,不用关系如何去异步编程,也让很多初级程序员也能够异步编程了。下面是一个使用Thread 多线程实现的异步例子,以及一个使用Async与Await的异步例子,接下来我们再简单理解下Async与Await的相关技术说明。
Thread多线程异步编程例子
class Program { static void Main(string[] args) { Console.WriteLine("主线程测试开始.."); Thread th = new Thread(ThMethod); th.Start(); Thread.Sleep(1000); Console.WriteLine("主线程测试结束.."); Console.ReadLine(); } static void ThMethod() { Console.WriteLine("异步执行开始"); for (int i = 0; i < 5; i++) { Console.WriteLine("异步执行" + i.ToString() + ".."); Thread.Sleep(1000); } Console.WriteLine("异步执行完成"); } }
以上代码运行效果如下图
使用Async与Await进行异步编程
1 static void Main(string[] args) 2 { 3 Console.WriteLine("主线程测试开始.."); 4 AsyncMethod(); 5 Thread.Sleep(1000); 6 Console.WriteLine("主线程测试结束.."); 7 Console.ReadLine(); 8 } 9 10 static async void AsyncMethod() 11 { 12 Console.WriteLine("开始异步代码"); 13 var result = await MyMethod(); 14 Console.WriteLine("异步代码执行完毕" + result.ToString()); 15 } 16 17 static async Task<int> MyMethod() 18 { 19 for (int i = 0; i < 5; i++) 20 { 21 Console.WriteLine("异步执行" + i.ToString() + ".."); 22 await Task.Delay(1000); //模拟耗时操作 23} 24 return 100; 25}
業績:
明白な私達はちょうど同じ同期方法を記述し、非同期メソッド、コード明確の準備を完了しました。
唯一のキーワード内部待つ非同期を使用する必要があります。非同期メソッドは、タスク、タスク<>または無効戻り値の型を有していてもよいです。
キーワードは、戻り値が「待機中」されて待機するために使用されているタイプ(awaitable)メソッド