按书上写的BeginInvoke方法问题求解

newpowersky 2016-08-12 11:00:41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BeginInvoke112
{
class Program
{
//定义一个委托
public delegate int sum(int a, int b);
//定义一个类
public class number
{
public int m =4;
//定义一个和委托一样签名的方法
public int numadd(int a, int b) {
return a + b;
}

//定义一个与AsyncCallback委托对应的回调方法
public void Callback(IAsyncResult ar)
{
sum s = (sum)ar.AsyncState;
m= s.EndInvoke(ar);

}
}

static void Main(string[] args)
{
number n = new number();
sum s1 = new sum(n.numadd);//把S1这个委托指向n.numadd方法
AsyncCallback async = new AsyncCallback(n.Callback);//回调方法把n.callback放入
s1.BeginInvoke(55, 33, async, s1);
Console.WriteLine("this sum is :{0}",n.m);
Console.ReadKey();
}
}
}

我按书上的代码打的。为什么结果出不了88呢。出的结果是M赋得值。如果M初始为0 就是0。
这个begininvoke的用法有什么不对吗?还是回调的写法有问题?
...全文
183 8 打赏 收藏 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
newpowersky 2016-08-17
  • 打赏
  • 举报
回复
大师,你的第一个是线程池,第二个是开一个新的线程,我还能看明白,第三个的
beginInvoke(null,null)
这里不太明白了。 我看得还真是10年的书,看样子这书不怎么行!谢谢大师的指导,
  • 打赏
  • 举报
回复
最近10年的、比较简练的写法,通常都不用你自己直接声明 delegate 类型了。使用“语法糖”和 .net 的默认 Action、Func 机制,可以更高效率地编程。 而对于 Sleep 代码问题,你会看到许多“博客”是胡乱地写了 Sleep 语句的,跟你最初的理由相同。可以说,这是不懂多线程编程造成的。理由有人在tcp、串口的事件处理或者异步回调处理方法中写 Sleep 语句,理由就是因为它自己搞不定正确的结果,但是又不去理解为什么出错,用一个 Sleep 来糊弄自己。 显然,正确的编程是一毫秒、一微秒的延迟都不需要故意去做的。因此从删除 Sleep 语句开始,你才可以了解设计多线程的算法跟设计单线程顺序过程的区别。
  • 打赏
  • 举报
回复
另外,这类程序直接写成
class Program
{
    public class number
    {
        public int m = 4;
        public void numadd(int a, int b)
        {
            m = a + b;
            Console.WriteLine("this sum is :{0}", m);
        }
    }

    static void Main(string[] args)
    {
        number n = new number();
        ThreadPool.QueueUserWorkItem(h => n.numadd(55, 33));
        Console.ReadKey();
    }
}
或者
class Program
{
    public class number
    {
        public int m = 4;
        public void numadd(int a, int b)
        {
            m = a + b;
            Console.WriteLine("this sum is :{0}", m);
        }
    }

    static void Main(string[] args)
    {
        number n = new number();
        new Thread(() => n.numadd(55, 33)).Start();
        Console.ReadKey();
    }
}
或者
class Program
{
    public class number
    {
        public int m = 4;
        public void numadd(int a, int b)
        {
            m = a + b;
            Console.WriteLine("this sum is :{0}", m);
        }
    }

    static void Main(string[] args)
    {
        number n = new number();
        new Action(() => n.numadd(55, 33)).BeginInvoke(null, null);
        Console.ReadKey();
    }
}
可能你学的是10几年前的 c# 的书。怎么你写出那么繁琐、累赘的代码呢?不累吗?
  • 打赏
  • 举报
回复
class Program
{
    //定义一个委托
    public delegate int sum(int a, int b);
    //定义一个类
    public class number
    {
        public int m = 4;
        //定义一个和委托一样签名的方法
        public int numadd(int a, int b)
        {
            return a + b;
        }

        //定义一个与AsyncCallback委托对应的回调方法
        public void Callback(IAsyncResult ar)
        {
            sum s = (sum)ar.AsyncState;
            m = s.EndInvoke(ar);
            Console.WriteLine("this sum is :{0}", m);
        }
    }

    static void Main(string[] args)
    {
        number n = new number();
        sum s1 = new sum(n.numadd);//把S1这个委托指向n.numadd方法
        AsyncCallback async = new AsyncCallback(n.Callback);//回调方法把n.callback放入
        s1.BeginInvoke(55, 33, async, s1);
        Console.ReadKey();
    }
}
Sleep 是很垃圾的,误导自己的。原本是要获得计算结果,只要产生结果就立刻显示结果。那么你如果写 Sleep 语句,要故意阻塞多久?付出这个代价还有什么必要使用多线程呢? 纠结 Sleep、“度太快了”,这都是错误的逻辑。你要从逻辑上搞明白流程(只要有结果就立刻打印结果,没有一毫秒延迟),就能搞懂 Sleep 是多么不靠谱的东西。。
newpowersky 2016-08-13
  • 打赏
  • 举报
回复
大概明白了谢谢高人.
巴士上的邂逅 2016-08-13
  • 打赏
  • 举报
回复
Endinvoke是执行完返回,你的代码中CallBack和打印不在一个线程。。。
newpowersky 2016-08-13
  • 打赏
  • 举报
回复
高人,我加了个
  number n = new number();
            sum s1 = new sum(n.numadd);//把S1这个委托指向n.numadd方法
            AsyncCallback async = new AsyncCallback(n.Callback);//回调方法把n.callback放入
            s1.BeginInvoke(55, 33, async, s1);
             Thread.Sleep(1000);//加入这句让主线程休眠
            Console.WriteLine("this sum is :{0}",n.m);
            Console.ReadKey();
这样的结果就是对的。书上的
 Console.WriteLine("this sum is :{0}",n.m);
这个代码是分了二段

 Console.WriteLine("this sum is :{0}");
 Console.WriteLine(,n.m);
所以有空执行完是这个意思吧。 为什么Endinvoke不是执行完后返回吗?为什么还没有返回就输出了?是速度太快了导致还没有执行回调就输出了?
巴士上的邂逅 2016-08-13
  • 打赏
  • 举报
回复
因为是异步操作,CallBack还没执行完就打印了,也就是说打印时m的值还是初始值

111,128

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧