這幾天無聊看書,《精通C#》和《C#圖解教程》,幾本書對比者看,都是舊版本的書,發現兩本書中的一個矛盾的地方:
《精通C#(第6版)》P571:說明:“如果異步調用一個無返回值的方法,僅僅調用BeginInvoke()就可以了。在這種情況下,我們不需要緩存IAsyncResult兼容對象,也不需要首先調用EndInvoke()(因為沒有收到返回值)。”
《C#5.0圖解教程》P432:說明:“因為EndInvoke是為開啟的線程進行清理,所以必須確保對每一個BeginInvoke都調用EndInvoke。”
兩本書中對此的觀點不一樣。
這是一個舊問題,很久很久以前大家就討論了,
哈哈哈,而且這是一個很無聊的問題,😅!
只是以前我不了解,今天我遇到了,故記錄於此。
其實關於BeginInvoke()和EndInvoke()是否一定要配對使用,是不是可以省略EndInvoke()的討論有很多,而且現在幾乎就沒有人在查閱這個問題了,因為現在大家都不在使用APM異步編程模式了!
但是既然我遇到了,那我就查一查唄
網上討論可以參考:
博客園:BeginInvoke 如果不調用EndInvoke會怎么樣?
CSDN : C#異步委托BeginInvoke是否必須和EndInvoke成對調用?
路人甲說:BeginInvoke()和EndInvoke()必須配對使用,以便清理線程池資源,
路人乙說:只要你不需要接收異步操作的返回值且不查看異步操作的狀態就可以不調用EndInvoke(),而且即使不用EndInvoke()清理線程,GC也會很快的清理用完的Delegate對象。
查閱StackOverFlow:Is EndInvoke() optional, sort-of optional, or definitely not optional?
可以看到最高贊答案如下,截圖翻譯了一下:
簡單的說在MSDN中兩中說法都有,寫不寫都可以!
好吧,一般我查閱問題可能就得出結論了,嘿嘿,但是我手賤又看了下面的一個18贊的答案,答案給了一個連接:
簡單的看看了,文章中說是一個大佬長期誤導了一些人,
理論上:
“CAUTION Always call EndInvoke after your asynchronous call completes.
”(注意,異步調用完成后一定要調用EndInvoke)
其次,文章提到:
“Microsoft obviously have the right to relax this requirement in the future if they want to, but for now, you have to call EndInvoke.
”
簡單的翻譯一下:微軟顯然有權利在將來放寬這一要求,但現在,您必須調用EndInvoke(哈哈,這句是2005年以前的情形,現在如何,就不考證了,嘿嘿!)
其實呀,簡而言之,調用EndInvoke一定沒壞處
我的理解就是,在沒有返回值的引用函數時實現異步,不使用EndInvoke,
就是相當於async & await
關鍵字實現返回值為void
的異步方法,
即不需要對該異步方法進一步交互,稱之為:調用並忘記(fire and forget),
許多時候異步編程就是需要這樣呀!只是現在我們一般都不使用APM模式罷了!