zoukankan      html  css  js  c++  java
  • C# 线程调用主线程中的控件

    由于项目的需要,最近几天一直在做串口和数据库。由于C#使用的时间不长,所以在编写代码和调试的过程中总是遇到意想不到的问题,比如在使用串口接收数据的时候,在接收数据事件中想把接收的数据放入一个textbox作显示,但是明明非常简单的代码,在编译的时候总是提示有错误。后来查看网上资料,才知道C#还有委托,匿名等等之类的新东西。下面我就把我这几天的经验和大家分享一下。这次就主要说说委托和匿名方法,以后在说说串口使用方面的经验。

    先说一下委托的基本概念,委托是一种引用型的数据类型,其实它的概念和C语言的函数指针几乎是一样的。回忆一下C语言的函数指针,定义一个函数指针,需要指定形参的类型和返回值的类型,只要有函数的形参类型和返回类型和这个函数指针一致,那么该函数指针就可以指向这个函数。C语言学习中一定会提高一个四则运算的例子,就是利用函数指针。

    C#中委托的申明如下

    【访问修饰符】 delegate 返回值类型委托名(【参数列表】);

    委托虽然是一种数据格式,但是却需要像类一下去实例化。所以委托的实例化如下

    委托类型委托变量名 = new 委托型构造函数(委托要引用的方法名)

    实例化过后就可以使用命名方法和匿名方法两种方法,来来指定这个委托的函数引用。

    废话少说,还是来一个实例吧。比如说,在主线程之外开辟一个线程,这个线程使用主线程的一个label控件,显示当前的时间。由于新开的线程要使用其他线程开的控件,所以需要使用到control类型的Invoke方法,而这个方法传入正是delegate类型。

    先来看一个“想当然”的代码。

    private void showDateTimeMethod()

    {

    while (true)

    {

        //显示当前时间

    label1.Text = "当前时间 " + DateTime.Now.ToString();

    //线程暂停

    Thread.Sleep(1000);

    }

    }

    private void Form1_Load(object sender, EventArgs e)

    {

    //新建一个线程

    Thread showDateTimethread = new Thread(new ThreadStart(showDateTimeMethod));

    //该线程为后台线程

    showDateTimethread.IsBackground = true;

    //线程启动

    showDateTimethread.Start();

    }

           用我的大腿想想,上面的代码应该是对的,但是由于net苛刻的安全机制,showDateTimeMethod中的代码是有错误的。为了解决这个错误可以声明一个委托类型,实例化一个委托变量(这话听起来很拗口),并给这个委托变量指定函数引用。

           方法一,使用命名方法

        //声明一个委托类型,该委托类型无输入参数和输出参数

    public delegate void ProcessDelegate();  

    //函数引用,label控件显示当前时间,输入参数无,输出参数无,和声明的委托类型形式一致

    public void LabelShow()

        {

            label1.Text = "当前时间 " + DateTime.Now.ToString();

    }

    然后在线程中实例化一个委托变量,指向这个函数引用。

    while (true)

    {

    //使用命名方法

    ProcessDelegate showProcess = new ProcessDelegate(LabelShow);

    //调用labelinvoke方法

        label1.Invoke(showProcess);

    //线程暂停

    Thread.Sleep(1000);

    }

    这样的话就可以在窗体中看到当前的时间了。

    方法二,使用匿名方法

    刚刚的函数引用只有区区一行,这一行完全可以使用匿名方法实现,如果使用匿名方法的话就可以免去编写一个函数,代码显得非常简洁。

    匿名方法使用方法也很简单。

    委托类型委托变量 = delegate (【参数列表】){代码块}

    while (true)

    {

    //实例化一个委托变量,使用匿名方法构造

    ProcessDelegate showProcess = delegate()

            {

               label1.Text = "当前时间 " + DateTime.Now.ToString();

            };

    label1.Invoke(showProcess);

    //线程暂停

    Thread.Sleep(1000);

    }

    方法三,使用MethodInvoker

    再观察一下上面的代码,这个委托类型,输入参数无输出参数也无,就可以使用C#MethodInvoker直接构造,关于MethodInvokerMSDN给出这样一个解释“表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法”

    //使用匿名方法2

    while (true)

    {

            label1.Invoke

           (

           //委托,托管无参数的任何方法

               new MethodInvoker

               (

                   delegate

                  {

                      label1.Text = "当前时间 " + DateTime.Now.ToString();

                   }

               )

    );

    //线程暂停

    Thread.Sleep(1000);

    }

    如果熟悉了C#的委托和匿名方法之后,那么在使用串口控件的时候就方便了很多。但是解决了旧的问题,新的问题也会到来。如果串口获得的数据很多,直接在接收的时候处理的话很难保证实时性,代码也变得很臃肿不堪。通过查阅网上的资料,想尝试使用异步的方法处理问题,即串口接收事件只负责接收数据,并把数据放入队列中一个线程每隔一段时间处理线程的内容,然后把整理好的数据放入数据库中。不过这要下次再说了啊。

     

    出自:http://blog.csdn.net/xukai871105/article/details/6204563

  • 相关阅读:
    JavaScript 为字符串添加样式 【每日一段代码80】
    JavaScript replace()方法 【每日一段代码83】
    JavaScript for in 遍历数组 【每日一段代码89】
    JavaScript 创建用于对象的模板【每日一段代码78】
    html5 css3 新元素简单页面布局
    JavaScript Array() 数组 【每日一段代码88】
    JavaScript toUTCString() 方法 【每日一段代码86】
    位运算
    POJ 3259 Wormholes
    POJ 3169 Layout
  • 原文地址:https://www.cnblogs.com/xiaofengfeng/p/3511906.html
Copyright © 2011-2022 走看看