Joe Albahari有一个关于多线程的伟大系列,这是一本必须阅读的内容,对于任何进行C#多线程处理的人来说都应该被人们所熟知.
然而,在第4部分中,他提到了易变的问题:
请注意,应用volatile不会阻止写入后读取交换,这可以创建脑筋急转弯.Joe Duffy通过以下示例很好地说明了这个问题:如果Test1和Test2在不同的线程上同时运行,则a和b最终都可能为0(尽管在x和y上都使用了volatile)
接下来是MSDN文档不正确的说明:
MSDN文档指出使用volatile关键字可确保始终在字段中显示最新值.这是不正确的,因为正如我们所见,可以重新排序读取后跟读取.
我查看了MSDN文档,该文档最后一次在2015年更改但仍列出:
volatile关键字表示某个字段可能被同时执行的多个线程修改.声明为volatile的字段不受编译器优化的约束,这些优化假定由单个线程进行访问.这可确保始终在字段中显示最新值.
现在我仍然避免使用volatile来支持使用陈旧数据的更冗长的线程:
private int foo;
private object fooLock = new object();
public int Foo {
get { lock(fooLock) return foo; }
set { lock(fooLock) foo = value; }
}
Run Code Online (Sandbox Code Playgroud)
关于多线程的部分是在2011年写的,这个论点今天仍然有效吗?是否应该不惜一切代价避免使用volatile或完全内存防护,以防止引入非常难以产生的错误,如上所述甚至依赖于它运行的CPU供应商?
任何人都可以解释为什么在按下切换3次后代码片段不起作用?
选中的属性仍设置为"已选中",但浏览器不再选中该复选框.
$(document).ready(function() {
$("#btn").click(function() {
if($("#chk").is(":checked"))
$("#chk").removeAttr("checked");
else
$("#chk").attr("checked","checked");
$("#lbldebug").text($("#chk").clone().wrap('<p>').parent().html());
});
});
Run Code Online (Sandbox Code Playgroud)
见http://jsbin.com/ewawih/2/edit
我在Opera和Chrome上都测试了它,两者都有同样的问题.
我在这里错过了什么?
我正在学习一些打字稿,但我不完全确定我的代码中的问题是什么.
我正在尝试实现一个事件系统,以通用的方式使我的域可观察(类似于C#与事件的关系)并且它编译顺利.当我注册一个处理程序时,它甚至会在intellisense(发送者?)中显示正确的类型推断.
但是当我尝试运行它时,我会在__extends帮助函数中得到一个"未捕获的TypeError:无法读取未定义的属性'原型'".
这是我的代码:
module Pathing.Domain {
export interface IEventArgs {
}
export interface EventHandler<S,T extends IEventArgs> {
(sender?: S, e?: T): void
}
export class StdEvent<S> extends EventDelegate<S, IEventArgs> {
}
export class EventDelegate<S, T> {
private handlers: EventHandler<S,T>[] = [];
public add(handler: EventHandler<S, T>): void {
this.handlers.push(handler);
}
public remove(handler: EventHandler<S, T>): void {
this.handlers = this.handlers.filter(h => h != handler);
}
public raise(...args: any[]): void {
for (var i = 0; i < this.handlers.length; i++)
this.handlers[i].call(this, args); …Run Code Online (Sandbox Code Playgroud)