相关疑难解决方法(0)

C#线程是否真的可以缓存一个值并忽略其他线程上该值的更改?

这个问题不是关于竞争条件,原子性,或者为什么要在代码中使用锁.我已经知道了.

更新:我的问题不是"存在易失性存储器的奇怪现象"(我知道它确实存在),我的问题是"没有.NET运行时抽象,所以你永远不会看到它".

请参阅http://www.yoda.arachsys.com/csharp/threads/volatility.shtml 和关于字符串属性本身线程安全的第一个答案吗?

(它们实际上是同一篇文章,因为一个引用另一个.)一个线程设置bool而另一个线程循环永远读取bool - 那些文章声称读取线程可能缓存旧值并且从不读取新值,所以因此你需要一个锁(或使用volatile关键字).他们声称以下代码可能永远循环.现在我同意锁定变量是一种好习惯,但我无法相信.NET运行时会真正忽略内存值的变化,如文章所述.我理解他们关于易失性内存与非易失性内存的讨论,我同意他们在非托管中有一个有效的观点代码,但我无法相信.NET运行时将无法正确地抽象出来,以便下面的代码能够满足您的期望.这篇文章甚至承认代码"几乎可以肯定"有效(虽然不能保证),所以我就索赔要求BS.任何人都可以验证以下代码是否真的有效?是否有人能够得到一个案例(也许你不能总是重现它)这个失败的地方?

class BackgroundTaskDemo
{
    private bool stopping = false;

    static void Main()
    {
        BackgroundTaskDemo demo = new BackgroundTaskDemo();
        new Thread(demo.DoWork).Start();
        Thread.Sleep(5000);
        demo.stopping = true;
    }

    static void DoWork()
    {
         while (!stopping)
         {
               // Do something here
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# multithreading

25
推荐指数
1
解决办法
5892
查看次数

受欢迎的"挥发性民意调查旗帜"模式是否破裂?

假设我想在线程之间使用布尔状态标志来进行协作取消.(我意识到最好使用一个CancellationTokenSource;这不是这个问题的重点.)

private volatile bool _stopping;

public void Start()
{
    var thread = new Thread(() =>
    {
        while (!_stopping)
        {
            // Do computation lasting around 10 seconds.
        }
    });

    thread.Start();
}

public void Stop()
{
    _stopping = true;
}
Run Code Online (Sandbox Code Playgroud)

:如果我在另一个线程上调用Start()0s和Stop()3s,那么循环是否保证在当前迭代结束时在10s左右退出?

我见过的绝大多数消息来源表明上述内容应该按预期工作; 见: MSDN ; Jon Skeet ; 布赖恩吉迪恩 ; 马克格拉维尔 ; Remus Rusanu.

但是,volatile只会在读取时生成获取栅栏,并在写入时生成释放栅栏:

易失性读取具有"获取语义"; 也就是说,保证在指令序列之后发生的任何内存引用之前发生.易失性写入具有"释放语义"; 也就是说,保证在指令序列中的写指令之前的任何存储器引用之后发生.(C#规格)

因此,正如Joseph Albahari所观察到的那样,无法保证不会(似乎)交换易失性写入和易失性读取.因此,后台线程可能会在当前迭代结束后继续读取_stopping(即false)的陈旧值.具体地说,如果我Start()在0和Stop()3s …

.net c# multithreading volatile memory-barriers

15
推荐指数
1
解决办法
745
查看次数

阻止C#编译器优化的'volatile'示例?

根据我的理解,C#中的'volatile'修饰符有两个效果:

  1. 根据需要为目标处理器插入栅栏
  2. 防止某些编译器优化

在x86/amd64上,(1)无关紧要.这些处理器不需要用于易失性语义的围栏.(虽然ia64不同.)

所以,我们归结为(2).但是,对于我尝试过的例子,volatile对jit-ted程序集没有任何影响.

我的问题是:你能举一个C#代码示例的例子,在字段上添加'volatile'修饰符会导致不同的jit-ted汇编代码吗?

.net c# concurrency synchronization volatile

6
推荐指数
1
解决办法
1234
查看次数

C#按下按钮后退出循环

我有一个简单的C#foreach循环,当按下按钮时如何突破循环?它不在backgroundWorker线程中,因此我无法使用backgroundWorker.CancellationPending.

c# foreach

2
推荐指数
1
解决办法
8682
查看次数