C#语法:多线程编程(Thread)

操作系统为了提高效率将一个进程分成多个线程。有一个主线程其他的都为子线程,在认识多线程前,我们的代码都是在主线程中执行的。都有一个规则就是 必须执行当前代码才会执行之后的代码。那么问题就来了,假如说有一个非常耗时的操作,比如加载数据或文件下载,难不成数据加载完之前,之后的代码以及其他代码都不执行吗?我们用过不少软件,比如迅雷、百度云,在下载文件的时候还可以进行其他操作,程序不会因为当前任务没执行完而停止。这就运用到了线程。如果将一个耗时10秒的操作放到主线程中,当程序执行到这段代码的时候就会卡机,也就是程序未响应。一种方法是用户等待10秒后让程序执行完,但大多数用户会选择后者:关闭程序。

一、Thread 类:(System.Threading.Thread)

表示托管线程,运行在.NET平台之上的,每一个Thread对象代表一个线程,多线程开发就有多个Thread对象。每一个线程都对应着一个任务(方法)。


二、示例代码;该窗体有3个控件一个label,两个button

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace Csharp窗体练习
{
    
   
    public partial class Form1 : Form
    {  
        
      
        public Form1()
        {
            
            InitializeComponent();
                   
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private int count = 0;
        private void btnCounter_Click(object sender, EventArgs e)
        {
                                                   
            Thread objThread = new Thread(delegate()  
            {
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);
                    if (label1.InvokeRequired)
                    {
                        label1.Invoke(new Action
  
  
   
   ((s,num) => { label1.Text = s+num;  }) , count.ToString(),i);
                    }
                }
            });
            objThread.IsBackground = true;
            objThread.Start();
            count++;
           
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            count=0;
        }
    }
}

  
  

首先第一步是创建Thread 对象: Thread objThread=new Thread(<参数>);Thread构造方法中有参数,可以选中Thread按F1查看帮助文档.翻开这些参数的定义:

public delegate void ParameterizedThreadStart(
	object obj
)

ParameterizedThreadStart其实就是一个无返回值带参数的一个委托。

public delegate void ThreadStart()

当然这就是一个无参数的委托。总结起来就是Thread构造方法里要放一个委托...所以上述使用了匿名方法当然也可以使用lambda表达式在匿名方法里写要操作的内容。

之后别忘了把线程IsBackground 属性设为true,默认为前台线程,设为true时为后台线程。前台线程与后台线程的区别是,应用程序必须在所有前台线程完成后才关闭,而后台线程,应用程序可以不考虑后台线程是否执行完,应用程序关闭后台线程自动关闭。如果你关闭了某个应用程序,但是在进程中发现该应用程序还在运行,说明该程序的前台进程还在运行。要么是编程的时候不注意,也有可能是流氓软件。

最后把线程start就可以了。

但是,在子线程中无法直接访问主线程的可视化控件,主线程和子线程就像各部门一样,做自己的事情,但是想随意访问内部消息是不允许的。虽然不能直接访问但是能间接访问呐,便可以使用Invoke()方法来实现。   Invoke(<delegate method>,object  args[]) ,第一个参数是通过委托调用的方法,之后的参数都是传给这委托的参数的值。在此之前判断InvokeRequired 是否必须调用Invoke方法。

Invoke方法第一个参数我用了Action。Action和Func都内置了委托,Action为无返回值的匿名方法,而Func有返回值   Func<参数1,参数2...,参数n,返回值>,除最后一个是返回值,之前的都是要传给方法的参数.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值