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
parameters and their updated valuesref
- 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的進階東東哦。
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的東東。找到的都是好東東哦。。
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這些玩意迷迷糊糊了。好吧,這些玩意說的差不多了,我已經把要點都講到了。