http://stackoverflow.com/questions/133270/illustrating-usage-of-the-volatile-keyword-in-c-sharp/1284007
这个贴子说程序出现列循环了,说解决问题是加volatile,但我照做后,为什么我的不会出现
以下是代码using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace ThreadVolatileTest
{
    class Program
    {
        int foo;
        static void Main(string[] args)
        {
            var test = new Program();            new Thread(delegate() { Thread.Sleep(500); test.foo = 255; }).Start();            while (test.foo != 255)
            {
                Console.WriteLine("OK");
            }
        }
    }
}因为我看了volatile这个的用法后,感觉和用Static没有什么差别
后发贴:今天看多线程的,但是对volatile这个关键字不理解,怎么感觉用static不是也是一样的效果吗
然后根据大牛们说的话,我理解为,难道我以前用的static 来做多线程的共享对像,得用volatile来?
然后我根据给出的测试示例,并没有测试出死循环的结果啊?
已编译为Release了谢谢

解决方案 »

  1.   

    你看看编译优化有没有打开:再不行的话你用Reflecotr看看编译后的dll的代码,是不是循环中的条件判断已经被优化掉了。
      

  2.   

    其实这个例子是要演示不用volatile会产生错误优化结果的情况,可以看到由于编译器越来越聪明,所以要演示出这种错误并不容易。
    搞死编译器不是目的,就是说多数情况下,在编码的过程中没有必要刻意去考虑某个成员变量是否要声明为volatile,可以让编译器自己去判断,如果测试发现错误了,再加上volatile不迟。
      

  3.   

    那我可不可以这样理解,,我就当我不知道这个volatile关键字
    因为昨天看多线程的时候有这个关键字,我感觉和我以前用static没有区别
    所以才会问这两个问题的
    谢谢
      

  4.   

    不能这样说,应该要知道,否则遇到我们讨论的例子中的这种情况,你就没法分析原因了。那你现在试出来死循环的情况了吗?要不然你把编译后的dll上传一份来看看?
      

  5.   

    http://pan.baidu.com/share/link?shareid=128753&uk=4212471801
    这个是当前这个示例的源码
    还有那个关闭记事本,还能得到数量1的代码我刚试了,我在第37次的时候,记事本那个得到了“1”
      

  6.   

    你的程序和stackoverflow上的例子是不同的。它的是这样的:
    while (test.foo != 255);
    Console.WriteLine("OK");
    可见只有像上面这样写,编译器才会把它优化成while(true);
    而你这样写:
    while (test.foo != 255)
    {
             Console.WriteLine("OK");
    }
    则不管foo是不是volatile,编译器都不会去优化。
      

  7.   

    我也试了50多次没出现错误。
    是不是你测试的时候按键按得太快,导致在notepad中输入了字符,退出的时候有提示“是否保存”?还有你给我的版本没有加WaitForExit等待,理论上是可能在退出前就执行了GetProcessesByName,不过我试了50几次也都是正常的提示0
      

  8.   

    我又试了下终于发现了确实会出现1,估计是process先退出,然后再从进程列表中删除。
    我加上Thread.Sleep(1);延迟1毫秒,然后又试了50多次,就没有发现问题了。