首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么SyncLock不在这里工作?

为什么SyncLock不在这里工作?
EN

Stack Overflow用户
提问于 2015-03-26 13:55:46
回答 2查看 3K关注 0票数 4

我正在开发一个类库,它将为CLR应用程序提供异步通信。

在BeginRead上有异步读取( SslStream ),其中有一个由多个流共享的回调例程。我不希望在调试期间并行处理回调,因此我创建了一个关键部分:

代码语言:javascript
复制
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

令我惊讶的是,这是行不通的,至少当我在SyncLock块中设置一个断点时是如此。多个流的回调同时在其中运行,而不需要在入口点等待直到前一个线程离开它。

单步执行特别是当流同时被关闭(关闭)时:流1执行行,流2执行行,1执行下一行,2执行下一行,等等。

我想您可能需要的不仅仅是一个通用的“新建对象”,但是我看到在堆栈溢出中至少有一个答案说明了我使用它的方式,只有“静态X作为新对象”在必须锁定的函数中创建同步对象。

是因为回调实际上来自.Net框架之外的一个.Net线程,SyncLock在这里不起作用吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-26 14:32:47

我以前从未见过在VB中使用static局部变量。这种事的存在对我来说是个新闻。我建议您使用传统的方法,使用shared类变量。

代码语言:javascript
复制
public Class Test
   Private shared SyncRoot As Object = new Object()

   Private Sub Callback_Read(ByVal ar As IAsyncResult)
      SyncLock SyncRoot 
         Dim ThisSslStream As SslStream = DirectCast(ar.AsyncState, SslStream)
         ...
      End SyncRoot
   End Sub

End Class
票数 2
EN

Stack Overflow用户

发布于 2015-03-26 15:09:45

代码语言:javascript
复制
    Static OneAtATime As New Object

静态关键字是VB.NET实现者脖子上相当沉重的磨石。他们必须支持它,因为它在以前的Visual版本中经常使用,忽略它会给想更新他们的工具的程序员带来太多的困难。

但是它的遗留行为与线程非常不兼容,这是.NET中非常支持的特性,以前没有问题,因为以前的VB版本不支持创建线程。为该语句生成的MSIL代码数量很大。您应该查看一下ildasm.exe实用程序。

它之所以庞大,是因为它需要做些什么。它只初始化变量一次,这是第一次输入该方法。不太难,它自动生成另一个布尔变量,以保持跟踪。但更困难的是,每一个线程都要做一次。换句话说,它具有ThreadStatic行为。

这就是在这里杀死你的原因,每个线程都有自己的SyncLock。这就是为什么您根本没有观察到同步:)您需要将它从方法中移出并声明为Shared

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29280314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档