0

我有一个 Web 应用程序,它在按钮上运行多个线程,单击每个线程在不同的 ipAddresses 上进行 IO 调用,即(登录 Windows 帐户,然后进行文件操作)。阈值为 30 秒。我假设如果超过阈值登录尝试,ipAddress 上的设备与我的条件不匹配,因此我不在乎。Thread.Abort() 不适合我等待 IO 调用完成的情况,这可能需要很长时间。

我尝试在阈值超时后立即根据线程状态进行数据库操作。它工作得很好,但是当我检查日志文件时,我注意到无响应线程的 thread.IsAlive 属性仍然是 true。在我的本地电脑上进行了几次调试后,我遇到了一个可能的死锁情况(我怀疑)我的电脑严重崩溃了。

简而言之,您对在执行 button_click 后立即杀死(强制)无响应线程(等待 IO 操作)有任何想法吗?

(PS:我没有使用线程池)

乌古占

编辑

为了进一步澄清,

我需要在每个 ipAddress 上验证给定的本地管理员凭据,并为后续的插入数据库记录。其余的,我不在乎。

在我的验证方法中,我首先调用了win32的logonuser方法,通过导入advapi32.dll来模拟管理员用户。之后,我尝试通过 Directory.CreateDirectory 方法在远程系统驱动器上创建一个临时目录,以检查授权。如果抛出了任何异常(UnauthorizedAccessException 或 IOException),那么远程机器就不感兴趣了,否则我们得到它,所以将它插入 DB。

我将验证方法称为给定 IP 范围的同步方式,它对一堆连续的端点工作得很好。但是当我针对一些不相关的 ipAddress 范围测试该方法时,每次验证尝试都需要 20 秒到 5 分钟才能完成。

然后我将我的设计转变为多线程方式,我决定在单独的线程中运行每个验证,并在阈值数量结束时中止无响应的线程。问题是 thread.abort 不太适合这种情况,它实际上等待 IO 指令的返回(我不想这样做)并在此之后引发 ThreadAbortException。

为了完成连续线程的执行,我忽略了无响应的线程并继续进行数据库操作并从按钮单击方法返回(此时无响应的线程仍然存在)。在执行按钮单击(在调试模式下)几次后出现严重的系统崩溃之前,一切似乎都很好。问题可能是 IIS 服务下的活动线程数量不断增加。

解决方案

线程没有及时响应的原因是找不到网络路径的情况。我的解决方案是在进行 IO 调用之前检查端口 135 上的 TCP 连接(Windows 上的 RPC 必须使用端口 135)。默认超时时间为 20 秒。如果您需要设置 timout,请使用 BeginConenct。另一个选项是 Pinging(如果在网络中启用了 ICMP)

4

1 回答 1

1

为什么你真的需要中止线程呢?为什么不让他们正常完成而忽略结果呢?(保留一个令牌以指示它所在的请求“批次”,然后记住您目前真正感兴趣的批次。)

另一种选择是保留用于进行 IO 调用的任何内容(例如套接字)并关闭它;这应该会导致发出请求的线程出现异常。

另一种选择是避免将请求放在不同的线程上,而是使用异步 IO - 您仍然可以获得并行性,但不会占用线程(只是 IO 完成端口)。另外,您不能对 IO 操作本身设置超时吗?请求应该以这种方式自然超时。

于 2010-04-02T16:36:04.927 回答