2012-06-04 28 views
3

背景:我的應用程序用於執行使用Selenium RC服務器的測試,偶爾當我對Selenium命令的調用沒有返回來自RC服務器的響應時,我遇到了問題 - 它然後結束阻塞正在執行測試的線程。.Net異步代理人工流產

示例代碼:

Private Delegate Function DoCommand_Delegate(ByVal command As String, ByVal args() As String) As String 
... 
asyncCommand = New DoCommand_Delegate(AddressOf server.DoCommand) 
asyncResult = asyncCommand.BeginInvoke(command, args, Nothing, Nothing) 
Try 
    ... (I have it use the AsyncWaitHandle to wait for periods of 10 seconds up to two minutes. At the end of each period it runs some checks for common problems that block Selenium from returning a response (modal dialogs) - I don't think that part is relevant to this question, it's just necessary.) 
Finally 
    result = asyncCommand.EndInvoke(asyncResult) 
... 

當時EndInvoke被調用時,工人代表已不是已經完成或者需要被中止。大多數情況下,它已經有一個響應,所以它工作得很好,但是在極少數情況下,Selenium RC的DoCommand沒有返回,所以線程鎖定在那裏。

最後,我的問題:是否有一種資源友好的方式來中止執行的委託,還是我需要將它轉換爲使用手動控制的線程可以中止和處置?

注意:這不是關於Selenium的問題,只是適當的多線程。

注2:我已經考慮過做在Finally以下調用EndInvoke前:

If Not asyncResult.IsCompleted Then asyncResult.AsyncWaitHandle.Close() 

...但我不知道這是否會真正正常工作,或者是什麼造成的損壞可能會導致。

+0

您無法安全地中止一個線程。 'Thread.Abort()'是危險的。 – SLaks

+0

@SLaks:我已經讀了很多關於'Thread.Abort()'的危險,所以我的意圖是找到最好的替代解決方案。鎖定線程顯然是最糟糕的選擇,不可接受。 'DoCommand'是非託管代碼,因此當它無法從遠程服務器(無論是否導致問題)中檢索響應時,我沒有選擇使其自行中止。這是我首先將'DoCommand'調用包裝到異步代理中的一部分。還有哪些其他選項可用? – TheDruidsKeeper

+0

真的沒有。 – SLaks

回答

0

有沒有辦法做到在同一時間如下:

  • 中止/終止線程非合作
  • 沒有破壞它(的AppDomain /處理)
相關聯的所有狀態

暗示:要麼合作終止(這裏不可能)或終止進程(由於涉及本地狀態,AppDomain不夠用),也不要終止線程。

你可以不殺死線程並將它掛在那裏。剩下的程序(剩下的測試)可以繼續執行。

我不會很高興看到這在生產中,但對於測試套件,這可能是好的(假設掛不能修復)。

爲什麼不能中止一個線程? Stack Overflow已經涵蓋了很多次。