2012-06-04 27 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已经涵盖了很多次。