如何在Web服务中生成线程并进行管理?

时间:2012-02-08 18:16:48

标签: .net multithreading web-services

我有一个Web服务,我需要抓取一堆记录并对每个记录进行一些处理。这个处理每行可能很长,我以线程方式运行这部分代码,将行的数据作为参数传递给函数。我可以处理1000行或更多行,并且我将数据处理线程的数量限制为10个。

要监视我的线程,我有一个Thread对象数组。

Dim RowThread(9) As Thread

在我生成一个新线程之前,在我的主线程(一个Web服务WebMethod)上,我循环遍历这个数组并查找我的下一个“可用”线程。

Dim avail_thread As Integer = -1
While avail_thread < 0
    For t As Integer = 0 To THREADCOUNT - 1
        If IsNothing(RowThread(t)) OrElse Not RowThread(t).IsAlive Then
            avail_thread = t
            Exit For
        End If
    Next
End While

...

RowThread(avail_thread) = New Thread(New ParameterizedThreadStart(AddressOf ProcessRow))

...

RowThread(avail_thread).Start(row)

正如您所看到的,它等待一个线程完成并将在下一个可用线程上生成下一行。如果所有10个线程都在使用中,它将继续循环并等到一个因为可用。

这种方法效果很好,并且在大多数服务器上运行良好。除了最近在某些服务器上,我注意到这会导致问题,因为它在此循环中将CPU固定。这会影响整体性能,因为我的主线程浪费了大量的CPU周期。为了简化这一点,我尝试了线程Sleep()甚至DoEvents(),但这些方法只会进一步降低性能。

还有其他人遇到过这种情况吗?我真的不认为我可以使用委托等等。因为这是在Web服务中,我不希望我的主调用结束,因为我不希望在处理完所有行之前发送结果。与ThreadPool相同的问题,更不用说ThreadPool会给你尽可能多的控制权。

如何负责生成然后从Web服务中管理线程?有没有办法执行非阻塞手动线程监控?

2 个答案:

答案 0 :(得分:2)

为什么不将所有工作发布到线程池?它将以完美正确和有效的方式为您完成所有这些工作。它将创建正确数量的线程并在它们之间分配工作项。当您使用TPL的Task类时,您甚至可以监视任务完成情况。

答案 1 :(得分:0)

我想我在WaitHandle找到了答案。在我以前的研究中,我认为只能将它们与ThreadPool一起使用,但事实证明你可以将它们与手动启动的线程一起使用。

我现在用:

RowEvents(avail_thread) = New ManualResetEvent(False)

然后稍后将其作为我的参数对象的一部分传递给线程Start。当该函数完成时,我在该线程的ManualResetEvent对象上执行Set()。

我现在找到下一个可用的线程代码如下:

Dim avail_thread As Integer = -1
While avail_thread < 0
    For t As Integer = 0 To THREADCOUNT - 1
        If IsNothing(RowThread(t)) OrElse Not RowThread(t).IsAlive Then
            avail_thread = t
            Exit For
        End If
    Next
    'All threads busy, call blocking wait
    If avail_thread < 0 Then avail_thread = WaitHandle.WaitAny(RowEvents)
End While

这将在第一遍传递所有10个线程。如果它们都在运行,那么我调用WaitAny方法,当任何线程完成时返回焦点并将我的avail_thread变量设置为完成的索引线程