c#Task、Thread、线程、进程、线程池

一、Task概念

1、什么是进程?

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,【是系统进行资源分配的基本单位】,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,【进程是线程的容器】。程序是指令、数据及其组织形式的描述,进程是程序的实体。

简单概括:进程是程序运行的环境。进程是线程的容器。一个进程可以包含多个线程。
进程系统进行资源分配的基本单位,而线程是系统进行资源分配的最小单位(线程不能再分)。

2、什么是线程?

线程(英语:Thread)是操作系统能够进行【运算调度的最小单位】。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
简单概括:线程是操作系统资源调度的最小单位。线程不能独立运行,必须包含在进程中。进程中可以包含多个线程。多线程执行时是并行,无序的。

串行===>排队===>阻塞(同步)   并行===>无序===>非阻塞(异步)

线程之间要通讯。会有两种方案:同步和异步。

单个线程中能不能异步?可以

多线程肯定是异步。异步不一定是多线程。

多线程中有N个线程,但主线程只有一个,其他的线程都称为分线程。对于单线程程序来说,程序中只有一个线程,这个线程就是主线程。

3、多线程的概念?优点和缺点?

多线程是指程序中包含多个执行流(线程),即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

概括:多线程让程序同时运行多个线程,多个线程并行执行(执行时无顺序)

优点:可以提高CPU的利用率。大大提高了程序的运行效率

缺点:
a.线程也是程序,所以线程运行需要占用计算机资源,线程越多占用资源也越多。(占内存多)
b.多线程需要协调和管理,所以需要CPU跟踪线程,消耗CPU资源。(占cpu多)
c.线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题。(多线程存在资源共享问题 锁)
d.线程太多会导致控制太复杂,最终可能造成很多Bug。(管理麻烦,容易产生bug)

4、什么是线程池?
.NET Framework2.0时代,出现了一个线程池ThreadPool,是一种池化思想,如果需要使用线程,就可以直接到线程池中去获取直接使用,如果使用完毕,在自动的回放到线程池去;

概括:.net 2.0出现线程池,线程池中可以存在多个线程,让线程池来自动管理。

好处:解决了部分Thread管理不便的问题,移除了无用的Thread API。提高线程运行性能。

重要API:QueueUserWorkItem(Callback,data)

5、什么是Task任务?
Task在.net 4.0时出现,是在线程池基础上封装而来的,提供了对线程的延续,取消,等待,超时等方面功能。
Task提供了一种简单和强大的方式来处理异步编程

二、Thread

1、实例化一个分线程

Thread(任务):任务是运行在分线程上的;

Thread thread1 = new Thread(() => {
    Console.WriteLine("线程做的具体的工作,工作一般比较耗时");
    Console.WriteLine("将来也有可能把耗时的任务封装成方法");
});
thread1.Start();

2、obj向线程中传递的数据

Thread thread2 = new Thread((obj) => {
    Console.WriteLine("线程做的具体的工作,工作一般比较耗时2");
    Console.WriteLine("将来也有可能把耗时的任务封装成方法2");
})
thread2.Start();

3、Invoke()

分线程可以【获取】主线程中的资源,分线程中不能修改主线程中的资源,如果要修改分线程中的资源要使用Invoke(),跨线程调用也推荐使用。

Invoke(new Action(() => {
    label1.Text = "abc";
}))

4、线程的属性

thread1.IsBackground = true; // 后台线程
thread1.Name = "线程1"; // 线程名字
thread1.Priority = ThreadPriority.Normal;

5、winform窗体使用

Winform窗体上的所有的控件一般默认都在主线程中运行,主线程中的死循环:会阻塞,假死,卡顿。

private void button3_Click(object sender, EventArgs e)
{
    while (true)
    {
        Console.WriteLine("模拟耗时的任务");
    }
}

三、Task及工厂模式

1、Task实例化

1)通过构造函数(只实例化,不启动,没有返回值)、没有传递取消标识

Task t1 = new Task(() => {
    Thread.Sleep(1000);
    Console.WriteLine("任务1");
});
t1.Start();

2)可以取消的任务

CancellationTokenSource cts = new CancellationTokenSource();
Task t2 = new Task(() => {
    Thread.Sleep(1000);
    Console.WriteLine("任务2");
},cts.Token);  // Token标识符
t2.Start();

3)带参数的任务

Task t3 = new Task((obj) => {
    Thread.Sleep(1000);
    Console.WriteLine("任务3"+obj);
}, "hello");
t3.Start();

4)实例化并启动,Task.Run()有返回值,不能向任务传参。

Task.Run(() =>
{
    Thread.Sleep(1000);
    Console.WriteLine("任务1");
});

5)有返回值的任务 

Task<int> t1 = Task.Run(() =>
{
    return 123;
});
// 拿任务返回值  Result
Console.WriteLine(t1.Result);

6)没有返回值,没有参数,但可以取消任务

CancellationTokenSource cts = new CancellationTokenSource();
Task.Run(new Action(() =>
{
    Thread.Sleep(1000);
    Console.WriteLine("任务2");
}), cts.Token);
cts.Cancel(); // 取消任务

7)任务嵌套

Task.Run(() =>
{
    //return new List<int> { 1, 2, 3 };
    // 任务中又返回任务
    return new Task<string>(() => { return "hello"; });
});

2、Task工厂模式

带参数,带返回,带取消标识

CancellationTokenSource cts = new CancellationTokenSource();
Task<string> t3 = Task.Factory.StartNew((obj) =>
{
    Console.WriteLine("-------------");
    return obj.ToString();
}, "abc", cts.Token);
Console.WriteLine(t3.Result);

WhenAny 任务中的任何一个完成后继续执行的代码配合ContinueWith使用 

List<Task> list = new List<Task>()
{
    Task.Run(()=>{
        Thread.Sleep(3000);
        MessageBox.Show("one");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(6000);
        MessageBox.Show("two");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(10000);
        MessageBox.Show("three");
    })
};
Task.WhenAny(list.ToArray()).ContinueWith((r) =>
{
    MessageBox.Show("kkluv");
});

WhenAll 任务中的全部任务完成后继续执行的代码配合ContinueWith使用 

List<Task> list = new List<Task>()
{
    Task.Run(()=>{
        Thread.Sleep(3000);
        MessageBox.Show("one");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(6000);
        MessageBox.Show("two");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(10000);
        MessageBox.Show("three");
    })
};
Task.WhenAll(list.ToArray()).ContinueWith((r) =>
{
    MessageBox.Show("kkluv");
});

WaitAny 任务中的任意一个任务完成后继续执行的代码

List<Task> list = new List<Task>()
{
    Task.Run(()=>{
        Thread.Sleep(3000);
        MessageBox.Show("one");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(6000);
        MessageBox.Show("two");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(10000);
        MessageBox.Show("three");
    })
};
Task.WaitAny(list.ToArray());
MessageBox.Show("def");

WaitAll 任务中的全部任务完成后继续执行的代码

List<Task> list = new List<Task>()
{
    Task.Run(()=>{
        Thread.Sleep(3000);
        MessageBox.Show("one");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(6000);
        MessageBox.Show("two");
    }),
    Task.Run(() =>
    {
        Thread.Sleep(10000);
        MessageBox.Show("three");
    })
};
Task.WaitAll(list.ToArray());
MessageBox.Show("def");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值