XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2015/10/04

Async Await , C# 編譯器做了些甚麼事情呢–2?

在上一篇文章中 Async Await , C# 編譯器做了些甚麼事情呢– 1,我們將 WPF 內的非同步程式碼,透過編譯器的處理,產生了相對應的狀態機程式碼,並且在產生後的程式碼中,加入了詳盡的註解說明,並且說明了編譯器的處理過程。

在這篇文章中,我們將要補足上篇文章的一些不足點,那就是,在我們呼叫非同步程式之前,也就是 await 關鍵字之前,若還有些 C# 程式碼的話,而且,在這 await 關鍵字之後,繼續有使用到這些變數,那麼,在編譯器中所產生的狀態機物件會如何呈現?

(至於,同一個非同步方法中,若有多個 await 關鍵字,則狀態機內會使用 goto 來切換到不同的部分還處理,有興趣的人,可以自行針對編譯器產生結果程式碼來觀察)

底下為我在 WPF 的按鈕事件內呼叫一個非同步方法,在呼叫非同步方法之前,我們會計算 x * y * z 的數學運算結果到本地變數 total 內;並且在呼叫完成非同步方法之後,再將 total 變數的值,輸出到 Console上。

        private async void btnDownload2_Click(object sender, RoutedEventArgs e)
{
int
x = 3, y = 1, z = 2, total = 0;
total = x * y * z;

string
fooStr = await GetString2Async();
Console.WriteLine(
string.Format("{0} {1}", total,fooStr));
}

接著我們來看看,經過了編譯器的轉換,狀態機的類別,會如何定義呢?


我們特別將呼叫 await 非同步方法前的程式碼使用黃底色標示出來,而呼叫完成非同步方法之後的程式碼使用橘底色標示出來,您可以參考上一篇文章 Async Await , C# 編譯器做了些甚麼事情呢– 1 ,試著找出其中異同點。

        [CompilerGenerated]
private sealed class
<btnDownload2_Click>d__3 : IAsyncStateMachine
{
public int
<>1__state;

public
AsyncVoidMethodBuilder <>t__builder;

public object
sender;

public
RoutedEventArgs e;

public
MainWindow <>4__this;

private int
<x>5__1;

private int
<y>5__2;

private int
<z>5__3;

private int
<total>5__4;

private string
<fooStr>5__5;

private string
<>s__6;

private TaskAwaiter<string
> <>u__1;

void
IAsyncStateMachine.MoveNext()
{
int num = this
.<>1__state;
try
{
TaskAwaiter<
string
> taskAwaiter;
if
(num != 0)
{
this
.<x>5__1 = 3;
this
.<y>5__2 = 1;
this
.<z>5__3 = 2;
this
.<total>5__4 = 0;
this.<total>5__4 = this.<x>5__1 * this.<y>5__2 * this
.<z>5__3;
taskAwaiter =
this
.<>4__this.GetString2Async().GetAwaiter();
if
(!taskAwaiter.IsCompleted)
{
this
.<>1__state = 0;
this
.<>u__1 = taskAwaiter;
MainWindow.<btnDownload2_Click>d__3 <btnDownload2_Click>d__ =
this
;
this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter<string>, MainWindow.<btnDownload2_Click>d__3>(ref taskAwaiter, ref
<btnDownload2_Click>d__);
return
;
}
}
else
{
taskAwaiter =
this
.<>u__1;
this.<>u__1 = default(TaskAwaiter<string
>);
this
.<>1__state = -1;
}
string
result = taskAwaiter.GetResult();
taskAwaiter =
default(TaskAwaiter<string
>);
this
.<>s__6 = result;
this.<fooStr>5__5 = this
.<>s__6;
this.<>s__6 = null
;
Console.WriteLine(
string.Format("{0} {1}", this.<total>5__4, this
.<fooStr>5__5));
}
catch
(Exception exception)
{
this
.<>1__state = -2;
this
.<>t__builder.SetException(exception);
return
;
}
this
.<>1__state = -2;
this
.<>t__builder.SetResult();
}

[DebuggerHidden]
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
}
}

沒有留言:

張貼留言