天天看點

Asynchronous Method Invocation 【翻譯】 (四)

What they don�t want you to know about IAsyncResult

You should be wondering how

EndInvoke

is able to give us the output parameters and the updated

ref

parameters. Or, better yet, how

EndInvoke

is able to throw that exception we threw in our function. For example, say we called

BegineInvoke

on

Foo

, and then Foo finished executing, and now, we normally would call

EndInvoke

, but what if we decide to call

EndInvoke

20 minutes after

Foo

is finished? Notice that

EndInvoke

will still give you those output or

ref

parameters, and it would still throw that exception (if one was thrown). So, where is all that information stored? How come

EndInvoke

is able to get all that data long after the function is completed? Well� the key is with the

IAsyncResult

object! I decided to explore this object a little more, and as I suspected, it is this object that keeps all the information regarding your function call. Notice that

EndInvoke

takes one parameter, it is an object of type

IAsyncResult

. This object contains information such as:

  • Is the function completed?
  • A reference to the delegate used for

    BeginInvoke

  • All output parameters and their values
  • All

    ref

    parameters and their updated values
  • Return value
  • An Exception if one was thrown
  • And more�

他們不想讓你知道的 IAsyncResult

你應該知道了EndInvoke能給我們提供參數輸出,也能更新ref參數。在函數中EndInvoke能抛出異常。例如,我們用BeginInvoke調用函數Foo,接着Foo函數指向完畢,然後,通常我們會調用EndInvoke。但是,如果我們需要在Foo完成後20分鐘再要調用EndInvoke該怎麼辦那?EndInvoke仍然會做相應的output和ref參數的操作,仍然會抛出異常(如果異常存在的話)。所有這些資訊存在哪裡那?函數已經完成後那麼長時間,EndInvoke是怎麼把資料儲存的?好吧,答案就是IAsyncResult對象! 我覺得更多研究下這個對象,這個對象保留了所有的IAsyncResult相關的東東哦。這個對象包含了資訊如下:

* 函數是否完成?

* 為BeginInvoke提供的委托

* 所有輸出參數和他們的值

* 所有的ref參數和他們更新後的值

* 傳回值

* 如果異常存在,抛出異常

* 其他

IAsyncResult

may seem very innocent, because it is just an interface to a few little properties, but in fact, it is an object of type

System.Runtime.Remoting.Messaging.AsyncResult

.

IAsyncResult視乎很傻很天真(呵呵),因為他隻有一個接口和一些屬性,但實際上,它是一個對象,類型是System.Runtime.Remoting.Messaging.AsyncResult的進階東東哦。

Asynchronous Method Invocation 【翻譯】 (四)

Now, if we dig a little deeper, we will find that

AsyncResult

contains an object called

_replyMsg

of type

System.Runtime.Remoting.Messaging.ReturnMessage

, and what do you know� the holy grail has been found!

現在,如果我們深入研究,我們發現AsyncResult包含一個System.Runtime.Remoting.Messaging.ReturnMessage類型的叫什麼_replyMsg的東東。找到的都是好東東哦。。

Asynchronous Method Invocation 【翻譯】 (四)

I had to shrink the above image so you won�t need to scroll to the right to read it, you can simply click on the image to view it。

上面圖檔有點小,不行就點開檢視。

We can clearly see our return value, our output parameter, and our

ref

parameters. There is even an exception property to hold the exception. Notice that I expanded, in the debug window for

OutArgs

to show, the value 200 and a reference to the newly allocated

ArrayList

. You can also see in the property

ReturnValue

, the string �Thank you for reading this article�. If we had an exception, then the

EndInvoke

would throw it for us to catch it. I think this is proof enough to conclude that all the information regarding your function call is saved with that little

IAsyncResult

object you get back from

BeginInvoke

, it is like a key to your data. If we lose this object, we will never know our output parameters,

ref

parameters, and return value. It will also not be possible to catch an exception without this object. It�s the key! You lose it, and the info is lost forever in the maze of the .NET runtime� OK, getting a little carried away here. I think I made my point.

我們可以很清楚的看到傳回值,輸出參數,ref參數。甚至捕獲異常是的異常屬性。在展開欄裡,debug視窗可以看到OutArgs,值是200,

還有指向最新配置設定的ArrayList。你也可以看到ReturnValue屬性,字元"Thank you for reading this article".如果有異常的話,在EndInvoke會捕獲它而且抛出它。我想,這些東東能足夠讓我們推斷出函數所有的資訊都存放在IAsyncResult 對象裡,你能從BeginInvoke獲得。這是資料的關鍵要素。如果沒有這些東東,你就永遠不能知道輸出參數,ref參數,傳回值。永遠不能捕獲異常。這個是很關鍵很重要的東東哦。你要是弄丢了這樣東東,你就永遠對.NET這些玩意迷迷糊糊了。好吧,這些玩意說的差不多了,我已經把要點都講到了。

繼續閱讀