ActionWithRef 是自定义委托类型
 delegate void ActionWithRef<T1, T2>(T1 x, ref T2 y);

解决方案 »

  1.   

    异步的,如果你在异步方法后面直接访问value,那可能得不到数据,因为可能还未对他进行赋值
      

  2.   

    把value定义成全局变量再试
    value是个局部变量,异步执行的时候它已经变成未定义了才对
      

  3.   

    已经试过把value设置成全局,过了几秒之后再访问这个value还是0 
     private void button2_Click(object sender, EventArgs e)
    {
    MessageBox.Show(value.ToString());
    }
      

  4.   

    ref出来了又有什么用,等你异步执行完,使用p2的地方早就执行过去了
      

  5.   

    你这样写法比较有意思,个人猜测应该是异步不支持ref或者out之类的写法,或者你试试看用class,然后看值会不会变比如 class A;
    ref A
    A = new A();
      

  6.   

    int a = 1;
                int b = 2;
                ActionWithRef f3 = (int p1, ref int p2, string t) =>
                {
                    p2 = 3;
                    Console.WriteLine("P2:" + p2);
                    Thread.Sleep(1000);
                    Console.WriteLine(t + " B:" + b);
                };
                f3.BeginInvoke(a, ref b, "异步", null, null);            f3(a, ref b, "同步");
                Console.ReadLine();刚试了下,比较有意思的是:如果没同步的那段,的确出来是2,一旦有了同步那段,出来一定是3,不管结果是同步的console出来还是异步的先console出来
      

  7.   

    int a = 1;
                int b = 2;
                ActionWithRef f3 = (int p1, ref int p2, string t) =>
                {
                    
                    Console.WriteLine("P2:" + p2);
                    Thread.Sleep(1000);
                    p2 = 3;
                    Console.WriteLine(t + " B:" + b);
                };
                f3.BeginInvoke(a, ref b, "异步", null, null);            f3(a, ref b, "同步");
                Console.ReadLine();
    又试了下这个步骤,不同点出来了,如果异步的先console,那么结果就是2,否则就是3
      

  8.   

    那大家的结论是beginInvoke 不支持ref ?这个应该算是微软的一个Bug?
      

  9.   

    http://www.codeproject.com/Articles/10311/What-s-up-with-BeginInvoke
    找到了这篇帖子,没解释原因,只说明要避免这样做法,打开网页后搜索下reference 就能找到这段说明了
      

  10.   

    但如果真的要最后显示b的话,我觉得还是应该要在EndInvoke里面来console出来
      

  11.   

    starfd
    怎么你等级这么高呢?
      

  12.   

    调用委托跟直接调用方法不同!你可以认为调用委托,都是首先需要对所有参数“装箱封装”然后才调用的,于是实际上委托被调用时真正的最终的数据都在堆上而不是在栈上。而直接调用方法则不需要先将参数装箱。然后,对于BeginInvoke,它注册的委托“将来”才会被.net底层调用,于是与Invoke注册的委托的调用次序是有不同的,对(经过装箱之后的value变量)的影响时机就有先后不同。这些原因堆在一起,就造成了数据结果不一致。
      

  13.   

    我还测试过,使用 new thread.....线程的方式调用,上面测试用 ref 传入的参数可以正常赋值,但据我了解,thread 里面不能安全更新UI界面。
      

  14.   

    首先,不要混淆Delegate的BeginInvoke 和 Control的BeginInvoke,这是两个完全不一样的东西。如果你要异步更新UI,那是 Control的BeginInvoke。关于Delegate的BeginInvoke,见http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx。它有个Important说明,"No matter which technique you use, always call EndInvoke to complete your asynchronous call.",实际上那些ref和out的参数,都应该使用EndInvoke返回,它也给了个使用out的例子。
      

  15.   

    如果不调用EndInvoke,会导致系统资源泄漏,这才是最严重的问题。你可以试验,反复调用BeginInvoke,会看到进程使用的句柄数量不断增加。
      

  16.   

    虽然不知道为什么一定要调用EndInvoke……但个人反正习惯无返回值时直接通过threadpool的,4.0之后出了Task之后更是连threadpool都不用了