这个类的更好的线程模型?

时间:2009-12-10 20:37:38

标签: .net multithreading

我有一个名为Job的简单类,带有一个名为Run()的公共ctor和公共函数。

Run()将做一些工作,包括向第三方供应商提出请求,费用为$$$。在发出请求之前,它首先检查SQL Server数据库以查看数据是否已存在。发出请求后,它会将数据放入数据库中。

这是一个带有.NET WCF Windows服务后端的ASP.NET前端。该请求通过WCF调用进入,我将合同设置为InstanceContextMode.Singleton。对于那些不熟悉WCF的人 - 这只是意味着我的合同会将任何请求排队,直到当前的请求完成。在这里,我只需创建一个Job类的实例,从ctor中的用户发送输入参数,然后调用Run()函数。

这很好用,因为它是Singleton WCF服务,它会阻止重复请求转到供应商并且不需要花费成本计算$$。这些工作运行得足够快,以便一次只运行一份工作就好了。

然而,这对我来说仍然有点臭。作业类完全独立于WCF服务,以及任何调用者,如果需要,应该可以重复使用。

我怎样才能成为工作班,'自我线程安全'这么说?我的意思是 - 它现在设计的方式,工作类的调用者必须确保他不会同时运行两个工作,因为害怕创建一个不必要的欺骗请求。 / p>

有没有办法在作业类本身内部使用纯线程锁定?因此,如果我的类的用户创建了两个Job类实例并分离出两个调用Run()的线程,它会将第二个人排队等待直到第一个完成? (或任何数量的电话)。我不能只为整个Run函数使用Lock(),因为在我刚刚给出的示例中,他们只是将Run调用旋转到单独的线程中,使得Lock无用。我觉得这里有一些明显而简单的东西...... ??

注意 - 让它在整个过程中“自我管理”并不是我所关心的。我担心在多个线程中使用我的Job类的相同进程。对于前者,我只是将'检查数据库/调用供应商/插入数据库'放入单独的服务中。

由于

编辑:谢谢戴夫的回答。以下是证明它有效的代码:只需删除SyncLock行即可查看其是否正常工作。 (对不起,我们在工作时使用VB = P)

Public Class ThreadTest
    Private Shared syncObj As New Object()

    Private id As String
    Public Sub New(ByVal id As String)
        Me.id = id
    End Sub

    Public Sub Run()
        'remove this line to see the output change
        SyncLock syncObj
            For i As Integer = 0 To 1000
                Console.Write(id)
            Next
        End SyncLock
    End Sub
End Class

Module Module1
    Sub Main()
        Dim tt As New ThreadTest("1")
        Dim tt2 As New ThreadTest("2")

        Dim thread1 As New Threading.Thread(AddressOf tt.Run)
        Dim thread2 As New Threading.Thread(AddressOf tt2.Run)

        thread1.Start()
        thread2.Start()

        Threading.Thread.Sleep(Threading.Timeout.Infinite)
    End Sub
End Module

1 个答案:

答案 0 :(得分:3)

这取决于您的应用程序的结构,但您可能能够锁定Job类中的私有静态对象变量。

private static readonly object lockObject = new object();

public void Run()
{
    lock (lockObject)
    {
        // Do a bunch of stuff here.
    }
}