在我的公司,我们确实拥有需要准确时间的关键系统.
因此,我们有一个带有室外GPS天线的NTP服务器设备,可以从GPS卫星接收时间.
我的问题是:
谢谢,
我已经在VB.NET中做了一段时间的简单多线程,并刚刚进入我的第一个大型多线程项目.我总是使用Synclock
声明完成所有事情,因为我认为没有更好的方法.
我刚刚了解了这个Interlocked
类 - 它看起来好像这一切:
Private SomeInt as Integer
Private SomeInt_LockObject as New Object
Public Sub IntrementSomeInt
Synclock SomeInt_LockObject
SomeInt += 1
End Synclock
End Sub
Run Code Online (Sandbox Code Playgroud)
可以用单个语句替换:
Interlocked.Increment(SomeInt)
Run Code Online (Sandbox Code Playgroud)
这会在内部处理所有锁定并修改数字.这比为简单操作编写自己的锁要简单得多(更长时间运行或更复杂的操作显然仍然需要自己的锁定).
当我可以使用这些Interlocked
方法完成同样的事情时,我是否有理由使用专用锁定对象来进行自己的锁定?
假设我有一个字节数组,Private Data as Byte()
。该数组在类中是私有的。该类提供对进行读写的公共功能Data
。
可以通过多个线程访问该类,因此我想避免发生一种情况,即不会同时发生读取和写入操作的情况。
目前,我正在使用SyncLock以避免问题。我可以SyncLock Data
只放入写函数,还是必须在读函数中?或两者?
我没有特定的代码示例。我只是很好奇,如果写入功能的SyncLock首先使写入具有对其的独占访问权,那么锁定读取和写入功能是否有任何好处。
vb.Net多线程问题:
有什么区别
SyncLock syncRoot
''# Do Stuff
End SyncLock
Run Code Online (Sandbox Code Playgroud)
-和-
SyncLock Me
''# Do Stuff
End SyncLock
Run Code Online (Sandbox Code Playgroud) 我有一个应用程序内服务,允许我从各种来源提供消息,这些消息将被放入一个简单的列表中.在自己的线程中运行的服务将定期将列表中的所有消息处理成各种文件; 每个源的一个文件,然后根据大小进行管理.
我的问题是关于检查消息和围绕访问列表的代码执行锁定的正确方法.只有两个地方可以访问该列表; 一个是将消息添加到列表的位置,另一个是将消息从列表转储到处理列表的位置.
将消息添加到列表:
Public Sub WriteMessage(ByVal messageProvider As IEventLogMessageProvider, ByVal logLevel As EventLogLevel, ByVal message As String)
SyncLock _SyncLockObject
_LogMessages.Add(New EventLogMessage(messageProvider, logLevel, Now, message))
End SyncLock
End Sub
Run Code Online (Sandbox Code Playgroud)
处理清单:
Dim localList As New List(Of EventLogMessage)
SyncLock _SyncLockObject
If (_LogMessages.Count > 0) Then
localList.AddRange(_LogMessages)
_LogMessages.Clear()
End If
End SyncLock
' process list into files...
Run Code Online (Sandbox Code Playgroud)
我的问题是:我在处理清单时应该仔细检查,见下文?为什么?或者为什么不呢?在锁定之外访问列表的count属性是否有任何危险?这些方法中的任何一种更好还是更有效?为什么?或者为什么不呢?
Dim localList As New List(Of EventLogMessage)
If (_LogMessages.Count > 0) Then
SyncLock _SyncLockObject
If (_LogMessages.Count > 0) Then
localList.AddRange(_LogMessages)
_LogMessages.Clear()
End If
End SyncLock …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个类库,它将为CLR应用程序提供异步通信.
SslStream上有异步读取(BeginRead),其中一个回调例程由多个流共享.我不希望在调试期间并行处理回调,所以我创建了一个关键部分:
Private Sub Callback_Read(ByVal ar As IAsyncResult)
Static OneAtATime As New Object
SyncLock OneAtATime
Dim ThisSslStream As SslStream = DirectCast(ar.AsyncState, SslStream)
...
End SyncLock
End Sub
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,这不起作用,至少在我在SyncLock块中设置断点时是这样.多个流的回调同时在其中运行,而无需在入口点等待,直到前一个线程离开它为止.
单步执行它是一场噩梦,特别是当流同时关闭(关闭)时:执行流1的行,执行流2的行,执行下一行1,执行下一行2,依此类推,通过整个块.
我想也许你需要的东西不仅仅是一个通用的"新对象",但后来我看到这里至少有一个关于堆栈溢出的答案,说明SyncLock正是我使用它的方式,只是"静态X作为新对象"在必须锁定的函数内创建同步对象.
是因为回调实际上来自.Net框架之外的win32线程,SyncLock在这里不起作用?
我已经创建了一个同步队列,并在调用Enqueue/Dequeue方法时在该队列的SyncRoot属性上使用SyncLock.从标准生产者/消费者类的实例调用这些方法.
这是SyncRoot属性的正确使用吗?
更好的做法是在每个类中创建一个私有共享对象并锁定它吗?
请解释一下你的推理.
以下代码摘自MS用于创建新的安全令牌服务网站的(Windows Identity Foundation SDK)模板.
public static CustomSecurityTokenServiceConfiguration Current
{
get
{
var key = CustomSecurityTokenServiceConfigurationKey;
var httpAppState = HttpContext.Current.Application;
var customConfiguration = httpAppState.Get(key)
as CustomSecurityTokenServiceConfiguration;
if (customConfiguration == null)
{
lock (syncRoot)
{
customConfiguration = httpAppState.Get(key)
as CustomSecurityTokenServiceConfiguration;
if (customConfiguration == null)
{
customConfiguration =
new CustomSecurityTokenServiceConfiguration();
httpAppState.Add(key, customConfiguration);
}
}
}
return customConfiguration;
}
}
Run Code Online (Sandbox Code Playgroud)
我对多线程编程比较陌生.我假设声明的原因lock
是在两个Web请求同时到达Web站点的情况下使此代码成为线程安全的.
但是,我会认为使用lock (syncRoot)
没有意义,因为syncRoot
引用此方法正在运行的当前实例...但这是一个静态方法!
这有什么意义?
我一直在阅读周围的内容,并得到了关于我是否应该在属性上使用同步锁的相互矛盾的答案。
我有一个多线程应用程序,需要跨线程获取/设置实例对象的属性。目前它是在不使用同步锁的情况下实现的,到目前为止我还没有注意到任何问题。我在常见的静态方法上使用同步锁,但我想以线程安全的方式正确实现我的实例类。
任何反馈将不胜感激。
我在一个类中有以下代码,它管理自动刷新某些对象,也允许您手动刷新。我想让它线程安全。
Public Function ForceRefresh() As Foo
DoRefresh()
ResetTimer()
Return Me.CurrentFoo
End Function
Private Sub DoRefresh()
Me._currentFoo = Me._retriever.GetTheFoo()
End Sub
Run Code Online (Sandbox Code Playgroud)
我很想尝试Synclock
这两种方法:
ForceRefresh
:所以我们不会有多个消费者线程尝试同时强制刷新并重置计时器DoRefresh
GetTheFoo()
:所以,如果我们已经在尝试找回一个,我们就不会尝试这样做。我正在使用System.Threading.Timer
它可能会回调任何线程ThreadPool
,因此简单地使用标志可能不合适(但也许仍然有必要?)... 像这样:
Private _syncRoot As New Object
Public Function ForceRefresh() As Foo
Synclock _syncRoot
'Snip ...
End Synclock
End Function
Private Sub DoRefresh()
Synclock _syncRoot
'Snip ...
End Synclock
End Sub
Run Code Online (Sandbox Code Playgroud)
但后来我在调用时最终尝试了Synclock
两次...现在如果是可重入的那么嵌套这些将不再是问题。MSDN文档页面似乎暗示了这种情况,但没有明确说明。_syncRoot
ForceRefresh
Synclock
注意:我自己会尝试一下,但我在 StackOverflow 上没有看到任何有关此问题的信息,并且认为这是一个需要回答的有用问题。
synclock ×10
vb.net ×6
.net ×2
c# ×2
clock ×1
gps ×1
interlocked ×1
locking ×1
properties ×1
time ×1