如何在 Option Strict On 的情况下将 Thread.VolatileWrite 与引用类型一起使用?
将参数包装在 CObj 或 DirectCast 中会关闭编译器,但该值仍未写入。
Option Strict On
Imports System.Threading
Module Module1
Dim str As String
Sub Main()
Thread.VolatileWrite(str, "HELLO") ' Compiler error.
Thread.VolatileWrite(CObj(str), "HELLO") ' Fails silently.
Thread.VolatileWrite(DirectCast(str), "HELLO") ' Fails silently.
Console.WriteLine(str)
End Sub
End Module
Wrapping the argument in CObj or DirectCast shuts the compiler up, but the value is still not written.
Option Strict On
Imports System.Threading
Module Module1
Dim str As String
Sub Main()
Thread.VolatileWrite(str, "HELLO") ' Compiler error.
Thread.VolatileWrite(CObj(str), "HELLO") ' Fails silently.
Thread.VolatileWrite(DirectCast(str), "HELLO") ' Fails silently.
Console.WriteLine(str)
End Sub
End Module
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有采用 String 参数的 Thread.VolatileWrite 重载。唯一支持的引用类型是 Object。
因为 VolatileWrite 正在更新变量 str 并且 Option Strict 为 On,所以编译器会抱怨,因为理论上 VolatileWrite 可能会尝试向该变量写入一个不是 String 类型的值(编译器只看到它可能写入任何对象)。事实上,由于 VolatileWrite 方法也只接受一个字符串,因此您可以编写尝试执行此操作的代码。由于超出本问题范围的原因,它会失败。
当您将表达式包装在 COjb/CType/DirectCast 表达式(实际上是带有括号的任何内容)中时,该变量不再被视为变量,而是一个值 - 它的处理方式与您在此处键入字符串文字的方式相同。由于值没有存储位置,VolatileWrite 的 ByRefness 被忽略,这意味着它不再写入,这意味着它不能再写入错误的值,这意味着编译器不需要再发出警告。
要通过字符串类型变量获得所需的行为,请在写入之前和读取之后使用 System.Threading.Thread.MemoryBarrier 方法。有关其他信息,请参阅此线程:我该如何指定 VB.net 中 volatile 的等效项?
There is no overload of Thread.VolatileWrite which takes a String argument. The only reference type supported is Object.
Because VolatileWrite is updating the variable str and Option Strict is On the compiler complains because in theory VolatileWrite could attempt to write a value to that variable which is not of type String (the compiler only sees that it might write any Object). In fact, as the VolatileWrite method also only takes a String you could write code which would attempt to do this. It would fail for reasons beyond the scope of this question.
When you wrap the expression in a COjb/CType/DirectCast expression (really anything with parenthesis) then the variable is no longer considered a variable but a value - it's treated the same way as if you'd just type a string literal there. Since values don't have storage locations the ByRefness of VolatileWrite is ignored which means it no longer writes which means it can no longer write a bad value which means the compiler doesn't need to warn anymore.
To get the behavior you want with a string type variable use the System.Threading.Thread.MemoryBarrier method before your writes and after your reads. See this thread for additional information: How do I specify the equivalent of volatile in VB.net?