タスクこんにちは、私たちはそれが再び会いました!!、ハハよあなたは、あなたがすでにタスクの前の4つの記事の私の要約を読んだことを、あなたは右であることを感じて、あなたがサポートして感謝非常に馴染みのオープニング挨拶ということではありません!問題ではない、私は前の4つの記事のアドレスを一覧表示されます記事の最後に、あなたが読み取りをクリックすることができ、それに慣れて感じることはありません。
以前の記事は、それが公共やブログ号公園があるかどうか、未来を共有し、小さなパートナーが列を求めている非同期I /のawait要約シェアは、そう、今日我々は、非同期/のawaitの話には、特別な何かを持っていることができ、この記事では、あなたも非同期の明確な理解だけでなく、使用する必要があります、ありがとうございました!
非同期/のawaitエントリ:
非同期は、我々は非同期メソッドを言って、まったくナンセンスではありません、最初の単純な例には多くの偉大な理論、で始まる実装し、この単純な例でChuxiang市をasyncdないでください!!
静的な 無効メイン(文字列[] argsを) { Console.WriteLineを($ " メインスレッドの開始、スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " )。 // 同期実装 AddSync(1、2 )。 // 非同期メソッドは待つない AddNoAwaitSyncHas(1、2 )。 // 非同期メソッド、そこ待つ AddHasAwaitAsync(1、2 )。 Console.WriteLineを($ " メインスレッドが終了すると、スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " )。 Console.ReadLine(); リターン; } /// <まとめ> /// 2つの数の和算出同期 /// </要約> /// <PARAM NAME = "NUM1"> パラメータ1 </ PARAM> /// <PARAM NAME = "NUM2"を> パラメータ2 </ param>の /// <戻り値> </戻り値> プライベート 静的の int型 AddSync(int型 NUM1、int型NUM2) { Thread.sleep(1000年); Console.WriteLineを($ " 同期方法、スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " ); 戻り NUM1 + NUM2。 } /// <まとめ> /// 2つのデジタル和(非同期メソッドが待つない) /// </要約> /// <PARAM名= "NUM1"> パラメータ1 </ PARAM> /// < paramの名前= "NUM2"> パラメータ2 </ param>の /// <戻り値> 結果</戻り値> プライベート 静的 非同期タスク< 整数 > AddNoAwaitSyncHas(int型 NUM1、int型NUM2) { Console.WriteLineを($ 「の前にいないのawait非同期スレッド、スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- 」); // 時間のかかるロジック関与すると想定される2つのデジタルサム、 のThread.sleepを(1000年); Console.WriteLineを($は、 " 非同期スレッド後、スレッドIDを待っていません:Thread.CurrentThread.ManagedThreadId} {\ N- " ); リターン NUM1 + NUM2。 } /// <まとめ> /// 2つのデジタル和(非同期メソッド、そこ待つ) /// </要約> /// <PARAM NAME = "NUM1"> パラメータ1 </ PARAM> /// < paramの名前= "NUM2"> パラメータ2 </ param>の /// <戻り値> 結果</戻り値> プライベート 静的 非同期タスク< 整数 > AddHasAwaitAsync(int型 NUM1、int型NUM2) { Console.WriteLineを($ 「のawait非同期スレッド、スレッドIDの前に:Thread.CurrentThread.ManagedThreadId} {\ N- 」); // 時間のかかるロジックの関与が想定される2つのデジタルサム、 VARに追加= 追加(NUM1を、NUM2); int型の結果は= 待つ追加します。 Console.WriteLineを($ " 非同期スレッドが待っていた後、スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " ); 戻り値の結果; } /// <まとめ> /// 2つの数のタスク和 /// </要約> /// <PARAM NAME = "NUM1"> パラメータ1 </ PARAM> /// <PARAM NAME = "NUM2" > パラメータ2 </ param>の /// <戻り値> 結果</戻り値> プライベート 静的タスク< 整数 >追加(int型 NUM1、int型NUM2) { // ロジックを実装するために時間がかかり想定 VARタスクTask.Run =(()=>を { Console.WriteLineを($ " 私は、タスク内部の実行開始午前:スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " ); Thread.sleep(5000 ); Console.WriteLineを($ " 私は、タスク内部実行を終了:スレッドID:Thread.CurrentThread.ManagedThreadId} {\ N- " ); リターン NUM1 + NUM2。 }); リターンタスク; }
結果:
我々は以下の結論を引き出すことができ、コードの実行と結果の分析を組み合わせます:
1は、非同期と同期の方法を記述することによって実現し、通話中に非常に似ています
非同期メソッド非同期キーワードを待っていない場合は2、その全体的な実行は、メインラインで実行されています
----同期呼び出し
図3は、非同期メソッド非同期キーワードは、スレッドがそのがのawaitに流域実行が待ちます
----、前の非同期実行を待つか、メインラインで実行
----のawait後、非同期実行ロジックは、新しいスレッドを開きます。
----それはまだその真の非同期のawait実現非同期(async)、あります
----修飾タスクが実際に変数または修飾戻り型タスクは、身体の方法である待ちます
----だから、最終的には最後の、非同期非同期または達成タスクによって
4、のawaitは、単独で使用することはできませんペアと非同期で使用する必要があります
----もちろんの修正方法aysncのawaitキーワードはできません
簡単な例は、上記の、それはそう、あなたは間違っていた、それは簡単です、そう簡単ではない、非同期メソッドを実装することが分かっていないが、あなたは、なぜ非同期メソッドは、複雑なのがいっぱいです実装し、求めることができます作成された非常に多くの方法が、そうではなく、より明確にするために、私が書いた、不安になり、その実行の流れを理解しています。さて、ここで我々は組成構造のaysncを探索するために一緒に来て/それを待っています!
組成構造のaysnc /で待っています:
実際には、非同期メソッドの全体的な構造と一般的なアプローチはあまり違いはありませんが、異なる点のみ、複数のタスクの論理的対象の、次のように要約のあらゆる側面を説明するのは簡単ですされています。
図は、上記全体で実行される方法の簡単な非同期の実行順序を描きます。
非同期メソッド呼び出し
個人的に私は何も言うことは非常に一般的なメソッド呼び出しとして、実際には、存在しないことを感じるが、非同期メソッドの呼び出しの結果は、一般的にTaskオブジェクトであることを特徴とする、あなたはその値を取得する必要があり、実行結果を得ている、または結果のためにいくつかのロジックを実行する必要があり、このとここでは詳しく説明しませ同様に、あなたはいくつかの記事を共有するために私の目の前で見ることができるクリアされていない、一般的なタスクを操作し、詳細な説明があるでしょう、あなたに感謝!
aysncメソッド本体
一例として、我々はすでに通常のメソッド本体に、ある非同期メソッドは、おそらく非同期が変更塗りつぶしそのシンプルな構造を追加することを知っている必要があります
プライベートaysncタスクMyAysnc(){}特定のメソッドの実装
戻り値の型についてAysncの話
次のように3例の戻り値の型は、さまざまなビジネスシナリオのそれぞれの場合に、あります。
A、Tsak:メインシナリオは、唯一の非同期メソッドの実行状態に関係メインプログラムを適用し、メインスレッドは、データ交換の結果のいずれかを有する必要はありません。
B、タスク<T>:メインシナリオは、主な関心事非同期メソッドの実行状態のみならず適用可能であり、また結果Tのデータ・タイプを実行した後に戻したいです
Cボイド:呼び出し側ではないので、メインプログラムでもない関係非同期メソッドの実行状態は、その実行の結果を気にしないが、主なプログラムは、非同期メソッドを呼び出して、イベントハンドラのコードに加えて、通常、非同期無効メソッドの使用を奨励していません
メインタスクロジック
aysnc为了实现异步,其中最关键的一个点就是await修饰符,await修饰的也就是task实现逻辑主体。task实现逻辑主体,其实在上就是一个task实例,所以其里面的实例逻辑使用和一个普通的task实例定义操作都是一样的,在此也就不在详细说明,前面的几篇文章也有详细的说明了,如果不清楚的可以查看以前的几篇文章。
aysnc/await的原理分析:
在说这一块之前,我们先把写的代码编译后,在通过反编译后发现在代码里面根本找不到aysnc/await关键词,有兴趣的小伙伴,你也可以这样操作分析一下。那么我们就明白了aysnc/await其实是编译器层面给的一个语法糖,是为了方便实现一个异步方罢了。
从反编译后的代码看出编译器新生成一个继承IAsyncStateMachine 的状态机结构asyncd(代码中叫<AddHasAwaitAsync>d__2),下面是基于反编译后的代码来分析的。
IAsyncStateMachine最基本的状态机接口定义:
public interface IAsyncStateMachine { void MoveNext(); void SetStateMachine(IAsyncStateMachine stateMachine); }
好了,说道这儿我们已经知道aysnc/await是编程器层面的一个语法糖,那么我们在来分析一下其执行的流程如下:
第一步:主线程调用 AddHasAwaitAsync(1,2)异步方法
第二步:AddHasAwaitAsync()方法内初始化状态机状态为-1,启动<AddHasAwaitAsync>d__2
第三步:MoveNext方法内部开始执行,task.run实现了把业务逻辑执行丢到线程池中,返回一个可等待的任务句柄。其底层还是借助委托实现。
第四步:到此程序以及开启了两个线程,一个主线程,一个task线程,两个线程相互独立互不阻塞,各自执行对应的业务逻辑。
好了,时间不早了,就先到这儿吧,感觉这一篇文章总结的不怎么好,先这样,后续我们在持续交流,谢谢!
猜您喜欢:
第一篇:聊聊多线程哪一些事儿(task)之 一创建运行与阻塞
第三篇:聊聊多线程那一些事儿(task)之 三 异步取消和异步方法
第四篇:聊聊多线程那一些事儿 之 四 经典应用(取与舍、动态创建)
END
为了更高的交流,欢迎大家关注我的公众号,扫描下面二维码即可关注,谢谢: