c#中委托、事件和回调

以前写的一个小程序,近来无事改来玩,有一个类执行一些事务性操作,通过winform窗口调用这个类,原来事务类的设计没有事件,在窗口调用时也没有使用多线程,这样就存在几个问题:

1. 事务运行事件长了的话,窗口就会假死,不响应用户的操作;

2. 事务类运行情况窗口不知道,不知道事务究竟执行到什么进度了;

于是就重构代码解决以上问题,第一步改写事务类


    public class clsXUT

    {

        public class Cls_Head

        {

        }


        const int StartIndex = 2244;        //第一份试卷头部的起始位置

        const int HeadLength = 1032;        //头部长度

        const byte DirFlag = 0;

        const byte FileFlag = 1;


        public List<Cls_Head> Head = new List<Cls_Head>();

        public event Action<int> progress;      //定义的事件

        public Action<int> p;                  //定义的回调函数,也就是一个没有返回值的委托

        private string xutfn;

        private string outpath;


        public clsXUT(string xutfilepath,string outdir)

        {

            xutfn = xutfilepath;

            outpath = outdir;

        }


        public void run()

        {

            FileStream fs;

            byte[] mmb = Resource1.mmb;

            fs = new FileStream(xutfn, FileMode.Open, FileAccess.Read);

            byte[] buf = new byte[HeadLength];

            while (true)

            {

                //if (progress != null)                                          //如果事件处理程序被绑定

                //    progress(Convert.ToInt32(fs.Position / fs.Length) * 100);  //激发事件

                if (p != null)

                    p(Convert.ToInt32(fs.Position / fs.Length) * 100);            //激发回调函数,函数在用户那里实现

                if (fs.Position >= fs.Length) break;                              //如果到文件结尾则退出

                if (fs.Position == 0) fs.Position = StartIndex;

                fs.Read(buf, 0, buf.Length);

                Head.Add(new Cls_Head(buf));

                Cls_Head head = Head.LastOrDefault();

                if (head.Flag == Cls_Head.FlagType.FileFlag)

                {

                    byte[] data = new byte[head.FileLength];

                    fs.Read(data, 0, data.Length); 

                    FileStream fw = new FileStream(outpath + "\\" + head.Path, FileMode.OpenOrCreate);

                    fw.Write(data, 0, data.Length);       

                    fw.Close();

                }

            }

            fs.Close();

        }


    }


窗口调用代码:

        private void button4_Click(object sender, EventArgs e)

        {

            //以多任务方式来调用事务类

            Task task = new Task(() =>

            {

                string path = textBox2.Text;

                xut = new clsXUT(textBox1.Text, path);               

                xut.progress += Xut_progress;              //使用事件

                xut.p += Xut_progress;                      //使用回调方法

                xut.run();

            });

            task.Start();                                  //启动任务,新版可以使用 dot net4.5使用Task.run(()=>{});

            //亦可使用线程,new Thread(()=>{}).Start()

        }


        private void Xut_progress(int pre)

        {

            if (this.InvokeRequired)

                this.BeginInvoke(new MethodInvoker(() => { progressBar1.Value = pre; }));

                //异步方式更新界面的进度条

        }


通过对比发现事件和回调函数其本质应该是一致的!有空再写个简单的对比程序,编译后看看有啥不同!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • http://blog.csdn.net/hit_why/article/details/54604908 简单易...
    不过一书生阅读 4,227评论 0 0
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 11,883评论 0 17
  • 英文文档,一开始我也是抗拒的,边翻译边看,也就花费了1个小时基本就阅读过了,我的英文基础其实很差。附上链接:链接:...
    lonecolonel阅读 13,464评论 3 1
  • 《see u again》 相信这首歌很多人都听过了,没错,纪念保罗沃克。 速7最后的镜头,保罗沃克开着代表天使颜...
    Final阅读 3,685评论 0 49
  • 2018年5月15日 每年的母亲节,总会收到峰峰的一封信。这是给我的礼物,也等于是一篇不命名的作文题。 对于物质的...
    幸运花开随笔阅读 1,774评论 0 2

友情链接更多精彩内容