ホームページ  >  記事  >  バックエンド開発  >  C# 5.0 関数 Async の詳細なグラフィック コード説明 (一目でわかる)

C# 5.0 関数 Async の詳細なグラフィック コード説明 (一目でわかる)

黄舟
黄舟オリジナル
2017-03-03 13:30:231336ブラウズ

Microsoft が Async CTP をリリースしてから約 1 か月が経ち、私たちの周りでは誰もが Async について話題になっています。すでに Async に精通している場合は、読み飛ばしてください... あなたが私と同じで、非同期プログラミングについては少ししか知らないが、以前の非同期プログラミングの方が面倒だと感じている場合は、一緒に探ってみましょう 次世代の C# が私たちに何をもたらすか見てみましょう。 (Async CTPVBもサポートしています。)


この記事の例は、Async CTP SP1 Refreshに基づいています。 Async はまだ CTP の段階にあるため、多くのことがまだ議論されているため、C# 5.0 がリリースされるときに詳細がまだ変更される可能性があります。ただし、一般的なアイデアとコンセプトは大きく変わるべきではありません。

本題に入りましょう:

まず、Async 機能を試すには、Visual Studio 2010 SP1Microsoft Visual Studio Async CTP ( SP1 リフレッシュ)

まず簡単なタスクを設定し、コールバックを使用して非同期プログラミングと Asyncプログラミング メソッドを改善する同期プログラミングを見てみましょう。次に、それらを通して分析してみましょう。 Async それは正確には何ですかそしてそれは私たちに何をもたらすのか。

タスク:

Windows Form アプリケーションを作成します。たとえば、ステータスを表す何かの計算を開始し、次に から計算します。 1 int.Max/2まで累積し、結果を表示します。

同期 これを行います:

まず、基本アルゴリズムを実装する関数を作成します:

  #region
 Do things

                     
public
 
long
 DoSomething(
int
 n)

                     {

                         
long
 result = 1;

                         
for
 (
int
 i = 1; i <= n; i++)

                         {

                             result += i;

                         }

                         
return
 result;

                     }
        #endregion


然后,添加一个按钮的Click事件处理程序:

 
private
 
void
 btnSync_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start to do something . . ."
;

                         
long
 value = DoSomething(
int
.MaxValue / 2);

                         lblResult.Text = value.ToString();

                     }


代码第一行改写Label的字样;第二行调用算法获得结果;第三行把结果输出。看似挺不算的。运行一下,就会发现有两个问题:

  1. 这个算法需要四五秒钟左右的实现时间,并且在这几秒钟的时间里,界面是锁死的,也就是说应用程序就像死了一样,它不接受任何用户操作。(也许我的电脑比较差,呵呵,所以,如果你没有遇到这种情况,请加大输入参数的值,让它算一会儿。)

  1. 我们没有看到Start to do something这一行字。

 

OK,出现这个现象也是可以理解的,因为我们把大量的运算添加到了UI线程里面了。所以,解决方法就是把它放到外面。我试了一下不用Async,实现的代码如下:

private
 
void
 btnCallback_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start to do something . . ."
;

                         Func<
int
, 
long
> callBackDelegate = 
this
.DoSomething;
            callBackDelegate.BeginInvoke(

                             
int
.MaxValue / 2,

                             
new
 AsyncCallback(

                             a =>

                             {

                                 lblResult.Invoke(
new
 MethodInvoker(() =>

                                     {

                                         lblResult.Text = callBackDelegate.EndInvoke(a).ToString();

                                     }));

                             }),

                             
null
);

                     }


如果你觉得这段代码比较晕,那就跳过这一节吧。可能我代码写得不好,大家将就看我简单解释一下,我首先给DoSomething写了一个代理,然后,调用了代理的BeginInvoke方法,把算法放到了其它的Thread中去调用了。这个代理执行完了以后,因为它不会直接返回一个long型的值,而是会去执行一个AsyncCallBack,所以,就在这个Callback里,去调用这个代理的EndInvoke()

 

好吧,且不论代码质量,这个就是有Async之前的一种实现异步的方法。

从这个代码里,我们完全看不到原来代码的影子,我也没有办法像解释同步代码一样解释:第一、第二、第三……有了Async之后呢?呵呵,代码说明一切:

public
 
Task
<
long
> DoSomethingAsync(
int
 n)

                     {

                        
return
 
TaskEx
.Run<
long
>(() => DoSomething(n));

                     }
 
        
private
 
async
 
void
 btnAsync_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start do something..."
;

                         
var
 x = 
await
 DoSomethingAsync(
int
.MaxValue / 2);

                         lblResult.Text = x.ToString();

                     }


3 つのこと:

最初: ファイル参照を追加します: AsyncCtpLibrary.dllAsyncが正式にリリースされた後、これは.NETアプリケーションセットに登場すると信じています。

2 番目: DoSomethingTask にカプセル化します。

3 番目: asyncawait などのキーワードを追加します。

コードを詳しく見てみましょう:

まず、非同期で実行されるコードの戻り値を Task8742468051c85b06f0a0af9e3e506b5c として記述します。この戻り値には実際には 3 つのオプションがあります: voidTask、および Task8742468051c85b06f0a0af9e3e506b5c の使用方法の詳細については、C の MSDN を確認してください。 #4.0 タスク カテゴリ。

次に、TaskExRun4db15037c2d45d75b28ec2b6a696f099メソッドを呼び出し、戻り値がlongのメソッドを渡しました。これはタスクのアルゴリズムです。

勉強することに興味がある場合は、Run8742468051c85b06f0a0af9e3e506b5cが実際にTask.Factory.StartNew8742468051c85b06f0a0af9e3e506b5cを呼び出す、そしてこれはStart48c15ee73f6e332a8a171e10c6563c6cを見てください。 まず Task を構築し、次にその Start メソッドを呼び出しました...

さて、アルゴリズムをタスクに封印し、部分的に完了します。

コードの 2 番目の部分は、より簡単に説明できます。

最初の行は、Label という単語を書き換えます。 2 行目は、結果を取得するためのアルゴリズムを呼び出します。 <--この銀行は前の記事から/をコピーしました:-)

笑、詳しく見てSyncを比較してみましょう非同期のコード:

同期

非同期

private void btnSync_Click(object sender, Event引数 e)
                    {
                        lblResult.Text =
「何かを始めてください . . .」;
                        
long value = DoSomething(int.MaxValue / 2);
                        lblResult.Text = value.ToString();
                    }

private async void btnAsync_Click(object sender, EventArgs e)
                    {
                        lblResult.Text =
「何かを始めてください...」;
                        
var x = await DoSomethingAsync(int.MaxValue / 2);
                        lblResult.Text = x.ToString();
                    }

まず、メソッド名に async を追加して、これが非同期呼び出しを持つメソッドであることを宣言します

次に、Task8742468051c85b06f0a0af9e3e506b5c の関数呼び出しを返します。 await キーワード (DoSomethingAsync) の前に。 xが何型なのか当ててみましょう?答えはロングタイプです。 await を使用すると、設計時であっても、コンパイラーは Task8742468051c85b06f0a0af9e3e506b5c の型を T 型に自動的に変換します。

コードはここで終わりますが、新しい Async 関数は何をもたらすのでしょうか?非同期プログラミングの能力でしょうか? Callbackを使用して非同期実装を実現することもできます。また、IAsyncCallbackインターフェイスは.NET 1.1にも以前から存在していました。 Task C# 4.0 で導入されました...

Async は、プログラマーにコードロジック中心のマルチスレッドプログラミングアプローチをもたらすと思います。最終的な比較により、AsyncのコードはSyncのコードとほぼ同じであることがわかります。プログラムは、コールバックや同期などの問題を考慮するために多大なエネルギーを費やす必要がなくなりました。 、など... これは C# とは異なります 私たちが取り組んできた方向性は同じです。プログラマーは、それをどのように行うかではなく、何を行うかを説明します。

最後に、アプリケーションのダウンロードとソースコード、および実行中のインターフェイスのスクリーンショットが添付されています... (わかりました、私はアーティストではありません、ご容赦ください:-)

)クリックソース コードをダウンロードするには

Async をクリックして、実行中のプロンプトを確認します:

実行結果を表示します:

最新かつ最も公式な Async 情報は次のとおりです。ここで: ^v^

http:// msdn.microsoft.com/Async

上記は、C# 5.0 の Async 関数の詳細なグラフィック コードの説明です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php) を参照してください。 .cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。