zoukankan      html  css  js  c++  java
  • 浅述WinForm多线程编程与Control.Invoke的应用

    在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来。一个最直接的方法便是使用多线程。多线程编程的方式在WinForm开发中必不可少。
    本文介绍在WinForm开发中如何使用多线程,以及在线程中如何通过Control.Invoke方法返回窗体主线程执行相关操作。

    -. WinForm多线程编程
    1. new Thread()

    新开一个线程,执行一个方法,没有参数传递:
    privatevoid DoWork() {
     Thread t =new Thread(new ThreadStart(this.DoSomething));
     t.Start();
     }

    private void DoSomething() {
     MessageBox.Show("thread start");
     }

    新开一个线程,执行一个方法,并传递参数:
    privatevoid DoWork() {
     Thread t =new Thread(new ParameterizedThreadStart(this.DoSomething));
     t.Start("guozhijian");
     }

    private void DoSomething(object o) {
     MessageBox.Show(o.ToString());
     }
    参数定义为object类型。
    2. ThreadPool
    众所周知,新开一个线程代价是很高昂的,如果我们每个操作都新开一个线程,那么太浪费了,于是,下面使用线程池。
    无参数传递:
    privatevoid DoWork(){
     ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething));
     }

    private void DoSomething(object o) {
     MessageBox.Show("thread start");
     }
    有参数传递:
    privatevoid DoWork() {
     ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething),"guozhijian");
     }

    private void DoSomething(object o) {
     MessageBox.Show(o.ToString());
     }
    使用匿名方法更灵活:
    privatevoid DoWork() {
    string name = "guozhijian";
     ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o){
     MessageBox.Show(name);
     }
    ));
     }
    在匿名代码段里面可以直接访问局部变量,不用在关心参数传递的问题
    二. Invoke
    1. this.Invoke
    现在,在业务线程里面执行完毕,要改变窗体控件的值了,此时,如果直接通过this得到控件的句柄,然后对它进行操作是会抛异常的,.Net WinForm Application里面是不允许这样的操作的。这是,可以调用Invoke方法

    2.Invoke方法签名:
    object Control.Invoke(Delegate Method)
    object Control.Invoke(Delegate Method, params object[] args)

    3.使用自定义委托
    privatevoid DoWork() {
     WaitCallback wc =new WaitCallback(this.DoSomething);
     ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
     }


    private delegate void MyInvokeDelegate(string name);
    private void DoSomething(object o) {
    this.Invoke(new MyInvokeDelegate(this.ChangeText), o.ToString());
     }


    private void ChangeText(string name) {
    this.textBox1.Text = name;
     }
    哦,太麻烦了,难道我每次都要定义一个委托啊,这样可不行。

    4.使用System.Action:
    privatevoid DoWork() {
     WaitCallback wc =new WaitCallback(this.DoSomething);
     ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
     }


    private void DoSomething(object o) {
    this.Invoke(new Action<string>(this.ChangeText), o.ToString());
     }


    private void ChangeText(string name) {
    this.textBox1.Text = name;
     }
    本例传递一个参数,System.Action有很多个重载,可以无参数(非泛型),而最多可以有四个参数,同样采用匿名方法,不使用泛型形式的System.Action,如下:
    privatevoid DoWork() {
     WaitCallback wc =new WaitCallback(this.DoSomething);
     ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
     }


    private void DoSomething(object o) {
    this.Invoke(new Action(delegate(){
    this.textBox1.Text = o.ToString();
     }
    ));
     }

    5.使用System.Func
    如果Invoke调用主窗体操作之后,还希望在调用完得到一个返回值:
    privatevoid DoWork() {
     WaitCallback wc =new WaitCallback(this.DoSomething);
     ThreadPool.QueueUserWorkItem(wc,"Guozhijian");
     }


    private void DoSomething(object o) {
     System.Func<string,int> f = new Func<string, int>(this.GetId);
    object result = this.Invoke(f,o.ToString());
     MessageBox.Show(result.ToString());
     }


    private int GetId(string name) {
    this.textBox1.Text = name;
    if (name == "Guozhijian"){
    return 999;
     }

    else {
    return 0;
     }

     }

    result的值为 999。
    System.Func同样有很多泛形重载,这里不赘述。

    6.关于Invoke的拥有者:Control

    本文例中都是用this来引用,这里this替换为窗体任何一个控件的句柄都是OK的,因为Control.Invoke含义是将方法委托给拥有该Control的线程去执行。 

    转载:http://www.cnblogs.com/ghfsusan/archive/2011/12/28/2304310.html

  • 相关阅读:
    Building a Space Station POJ
    Networking POJ
    POJ 1251 Jungle Roads
    CodeForces
    CodeForces
    kuangbin专题 专题一 简单搜索 POJ 1426 Find The Multiple
    The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk's pool
    The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker
    The Preliminary Contest for ICPC Asia Xuzhou 2019 E. XKC's basketball team
    robotparser (File Formats) – Python 中文开发手册
  • 原文地址:https://www.cnblogs.com/aiwz/p/6153924.html
Copyright © 2011-2022 走看看