在COM編程中,COM線程模型的選擇是避免不了的。網(wǎng)上已有大量介紹“COM線程模型”的文章,在這里我只想說“STA 單線程套間”并不像想象中的那么簡單,在實際的開發(fā)中會出現(xiàn)“重入問題”。
“STA 單線程套間”,指的是一個線程只能建立一個套間,在線程中創(chuàng)建的COM對象只屬于這個套間,其他線程對此線程中COM對象的調(diào)用都必須通過代理對象串行調(diào)用。這樣,“STA 單線程套間”輕松解決了多線程之間的“同步問題”。
于是,我們將COM對象都采用“STA 單線程套間”,是不是就萬事大吉了呢?當(dāng)然不是。為了避免死鎖,所有的COM套間類型都支持重入,當(dāng)然“STA 單線程套間”也不例外。當(dāng)套間中的線程通過代理調(diào)用到其他套間中的對象的時候,調(diào)用者線程在等待此調(diào)用完成的過程中,它可以繼續(xù)處理其他的入方法請求。
例如,線程1中的對象a訪問線程3中的對象c,對象c又訪問線程4中的對象d。此時,線程4在處理傳入的調(diào)用,線程3在等待線程4返回,線程1在等待線程3返回。由于“STA 單線程套間”支持重入,所以,此時當(dāng)線程2中的對象b發(fā)起對線程3中對象c的訪問時,就會立即執(zhí)行。于是,線程3中的對象c就面臨著“重入問題”的考驗。
在一個多線程的程序中,這種“重入問題”的發(fā)生可能無處不在。如果我們忽視了這個問題的存在,那么在后續(xù)的開發(fā)中就會遇到許多莫名其妙的問題,而且極難糾錯。因為,我們的邏輯是對的,只是“重入問題”的發(fā)生,會將代碼的執(zhí)行環(huán)境(變量或循環(huán)結(jié)構(gòu)等)改變或破壞,使得程序無法再進行下去,或產(chǎn)生錯誤的結(jié)果。
想象一下,我們在每實現(xiàn)一個COM對象的方法時,都要評估這個方法會不會產(chǎn)生“重入問題”,如果發(fā)生“重入問題”,這個方法內(nèi)的執(zhí)行環(huán)境(變量或循環(huán)結(jié)構(gòu)等)是否會被改變或破壞,是否需要對其他地方的代碼進行調(diào)整。如果是這樣的話,“重入問題”比“同步問題”輕松不了多少。
“STA 單線程套間”,指的是一個線程只能建立一個套間,在線程中創(chuàng)建的COM對象只屬于這個套間,其他線程對此線程中COM對象的調(diào)用都必須通過代理對象串行調(diào)用。這樣,“STA 單線程套間”輕松解決了多線程之間的“同步問題”。
于是,我們將COM對象都采用“STA 單線程套間”,是不是就萬事大吉了呢?當(dāng)然不是。為了避免死鎖,所有的COM套間類型都支持重入,當(dāng)然“STA 單線程套間”也不例外。當(dāng)套間中的線程通過代理調(diào)用到其他套間中的對象的時候,調(diào)用者線程在等待此調(diào)用完成的過程中,它可以繼續(xù)處理其他的入方法請求。
例如,線程1中的對象a訪問線程3中的對象c,對象c又訪問線程4中的對象d。此時,線程4在處理傳入的調(diào)用,線程3在等待線程4返回,線程1在等待線程3返回。由于“STA 單線程套間”支持重入,所以,此時當(dāng)線程2中的對象b發(fā)起對線程3中對象c的訪問時,就會立即執(zhí)行。于是,線程3中的對象c就面臨著“重入問題”的考驗。
在一個多線程的程序中,這種“重入問題”的發(fā)生可能無處不在。如果我們忽視了這個問題的存在,那么在后續(xù)的開發(fā)中就會遇到許多莫名其妙的問題,而且極難糾錯。因為,我們的邏輯是對的,只是“重入問題”的發(fā)生,會將代碼的執(zhí)行環(huán)境(變量或循環(huán)結(jié)構(gòu)等)改變或破壞,使得程序無法再進行下去,或產(chǎn)生錯誤的結(jié)果。
想象一下,我們在每實現(xiàn)一個COM對象的方法時,都要評估這個方法會不會產(chǎn)生“重入問題”,如果發(fā)生“重入問題”,這個方法內(nèi)的執(zhí)行環(huán)境(變量或循環(huán)結(jié)構(gòu)等)是否會被改變或破壞,是否需要對其他地方的代碼進行調(diào)整。如果是這樣的話,“重入問題”比“同步問題”輕松不了多少。