Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 我应该在代码中同步什么,在哪里?_Vb.net_Multithreading_Thread Safety_Synclock - Fatal编程技术网

Vb.net 我应该在代码中同步什么,在哪里?

Vb.net 我应该在代码中同步什么,在哪里?,vb.net,multithreading,thread-safety,synclock,Vb.net,Multithreading,Thread Safety,Synclock,我有一个类,其中有两个方法,一个调用一个类,该类创建并执行多个线程,另一个是一个事件处理程序,它处理这些线程完成时引发的事件(然后再次调用第一个方法) 我知道处理事件的方法在引发事件的线程中运行。因此,ISyncLock一个成员变量,表示有多少线程正在运行,并从中减去一个: SyncLock Me ' GetType(me) _availableThreads -= 1 End SyncLock 所以我有几个问题: 主要问题:我是否应该同步\u可用读取类中的所有位置,即在创建线程的方法

我有一个类,其中有两个方法,一个调用一个类,该类创建并执行多个线程,另一个是一个事件处理程序,它处理这些线程完成时引发的事件(然后再次调用第一个方法)

我知道处理事件的方法在引发事件的线程中运行。因此,I
SyncLock
一个成员变量,表示有多少线程正在运行,并从中减去一个:

SyncLock Me ' GetType(me)
    _availableThreads -= 1
End SyncLock
所以我有几个问题:

主要问题:我是否应该同步
\u可用读取类中的所有位置,即在创建线程的方法中(创建线程时添加1)

与此问题相关的补充问题:

  • 我通常会
    SyncLock
    当前实例,但我见过
    SyncLock
    s类型的代码,那么同步锁定
    Me
    (当前实例)和
    GetType(Me)
    之间的区别是什么呢

  • 两者之间会有性能差异吗?还有什么更小的东西我可以为上面的内容锁定,而不影响其他任何东西——可能是一个单独的“挂锁”对象,它的唯一目的是锁定类中的东西

  • 注意:
    \u availableThreads
    的唯一目的是控制在任何给定时间可以运行的线程数量,以及线程处理可能需要数小时才能运行的作业

    代码:

    公共类QManager
    Private _maxThreadCount,_AvailableThread读取为整数
    Public Sub New(ByVal maxThreadCount为整数)
    Me.MaximumThreadCount=maxThreadCount
    端接头
    公共子工作队列()
    //从队列中获取作业(优先级更改,所以每次都调用此选项)
    Dim jobQ As Queue(QdJobInfo的)=QueueDAO.GetJobList
    //在有作业且我们有可用线程时循环作业队列
    
    当jobQ.Count>0且_availableThreads时,不应
    SyncLock
    实例或类型。您总是希望对完全在类控制范围内的变量进行
    SyncLock
    ,而这两个变量都不是。您应该声明一个私有的
    新对象
    ,并将其用于
    同步锁

    Private lockObject as New Object()
    


    这里应该使用Interlocked类,Decrement()方法来减少计数。是的,无论在哪里访问变量


    使用SyncLock Me与SyncLock GetType(Me)一样糟糕。您应该始终使用私有对象来锁定,以便没有人会意外导致死锁。黄金法则是不能锁定数据,只能阻止代码访问数据。因为代码是您的私有实现细节,所以保存锁状态的对象也必须是私有细节。您的对象(我)或该对象的类型都不是私有的。意外地允许其他代码锁定它。

    不幸的是,您需要在这里做一些不同的事情

    首先,我建议避免使用SyncLock,并使用Interlocked.Increment和Interlocked.decreation来处理可用读取的更改。这将为没有锁的变量提供线程安全性


    也就是说,如果队列是从多个线程使用的,那么对队列的每次访问都需要一个同步锁。如果您使用的是.NET4,另一种选择是改用新类而不是队列。如果使用SyncLock,则应创建一个只能由类访问的私有对象,并将其用于所有同步。

    您可以用信号量替换线程计数器。若使用信号量,则无需退出while循环,也无需从ThreadCompleted事件处理程序调用WorkThroughQueue()。信号量是线程安全的,所以您可以在不锁定的情况下使用它


    非常有趣。。。我不知道这个互锁的类。谢谢。@Shoubs先生:不,不太好。如果您使用的是3.5,我建议您在私有对象上使用同步锁来访问队列,包括入队列和出队列。@Shoubs先生:只要您在队列完成之前不阻塞,就可以了。一旦线程的函数返回,线程就会消失,并有资格被垃圾收集。@Shoubs先生:看起来queuedJob.Process()启动了一个新线程。如果是这种情况,只要该方法返回,WorkThroughQueue就会返回,线程就会“消失”@Shoubs先生:在创建新线程后,逻辑将继续,旧线程就会消失,通常。。。但是,如果不看代码就很难知道。这是一个很好的信息,谢谢!我将研究我正在使用的方法和信号量,因为我也想了解如何连接线程。
    Private lockObject as New Object()
    
    SyncLock lockObject
       ...
    End SyncLock