C#中多线程的用法
1、在C#中使用多线程可以使用Thread
代码例子:
public class ThreadExample
{
public static void ThreadProc()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
}
}
public static void Start()
{
Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("主线程开始工作.");
}
Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.");
t.Join();
Console.WriteLine("工作结束");
Console.ReadLine();
}
}
internal class Program
{
static void Main(string[] args)
{
ThreadExample.Start();
}
}
由于我们写了 t.Join(); 所以,工作结束一定是最后一步进行的,但是。在Start方法中主线程和副线程是交替打印的,那么如何控制线程的进行呢?
有多种方法
在这之前,我先写一个例子,你们猜猜打印出来的结果是多少?
public class Sample1
{
public static void Show()
{
for (int i = 0; i < 5; i++)
{
new Thread(AddOne).Start();
}
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine("sum = " + sum);
Console.ReadKey();
}
private static int sum = 0;
public static void AddOne()
{
for (int i = 0; i < 100_0000; i++)
{
sum += 1;
}
}
}
可以看出来我将1000000累加了5次,但是结果不是5000000,原因就是在累加过程中,sum是交替执行的
所以,在这种情况下,我们必须使用同步锁,
public class Sample2
{
public static void Show()
{
object obj= new object(); //使用锁对象进行线程同步
for (int i = 0; i < 5; i++)
{
new Thread(()=>AddOne(obj)).Start();
}
Thread.Sleep(TimeSpan.FromSeconds(5));
lock (obj)
{
Console.WriteLine("sum = " + sum);
}
Console.ReadKey();
}
private static volatile int sum = 0;
public static void AddOne(object obj)
{
for (int i = 0; i < 100_0000; i++)
{
lock (obj)
{
sum += 1;
}
}
}
}
这样结果就是5000000了,但是正常开发中,我们一般用Task,很少用到Thread了,(代表我自己)
我们继续修改代码
public class TaskSample1
{
public static void Show()
{
var task=Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
}
});
task.Wait();
for (int i = 0; i < 100; i++)
{
Console.WriteLine("主线程: 执行方法。");
}
Console.WriteLine("主线程:ThreadProc。加入已恢复。按“Enter”结束程序。");
Console.ReadLine();
}
}
但是如果我们的Task很多呢 需要 Task.WaitAll(tasks);
public class TaskSample2
{
public static void Show()
{
Task[] tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
tasks[i] = Task.Run(() => Thread.Sleep(2000));
}
try
{
Task.WaitAll(tasks);
}
catch (AggregateException ae)
{
Console.WriteLine("One or more exceptions occurred: ");
foreach (var ex in ae.Flatten().InnerExceptions)
Console.WriteLine(" {0}", ex.Message);
}
Console.WriteLine("Status of completed tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
Console.WriteLine("主线程:ThreadProc。加入已恢复。按“Enter”结束程序。");
Console.ReadLine();
}
}
现在我们已经学会基础的线程控制了,
但是一个任务的进行,会遇到很多的问题,不是你简单的写两个任务,这两个任务就会按照你的想法去执行下去
比如,
1、在执行下载任务的时候没电了,
2、在执行下载任务的时候想取消了
这个时候,你该怎么做呢
看代码:
public class Sample4
{
public static void Show()
{
CancellationTokenSource cts = new CancellationTokenSource();
// 可以直接设置10秒后任务停止 CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
cts.Token.Register(() => { Console.WriteLine("任务已停止"); });
Task.Run(() =>
{
int i = 0;
while (!cts.IsCancellationRequested)
{
i++;
Console.WriteLine(i);
Task.Delay(1000).Wait();
}
});
// cts.CancelAfter(5000); //5秒后取消操作 也可以使用Cannel直接取消
//这个可以用在你下载文件,或者读取文件出错的时候使用
//也可以设置按下ESC键时任务停止
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Escape)
{
cts.Cancel();
}
Console.ReadLine();
}
}
这段代码中,你每隔一秒累加1,功能就是按下ESC键,停止累加操作,结束程序
CancellationTokenSource你把它当作一个回调函数,
可以在任务进行的时候取消任务,
在C#中About()方法已经过期了,现在大多数都用CancellationTokenSource来代替。
我在上面写过, object obj= new object(); //使用锁对象进行线程同步
我们要同步线程的时候用到。
但是在大型项目中,我们还是用AutoResetEvent锁和ManualResetEvent锁,我在下期再讲
C#中多线程的用法的更多相关文章
- qt中多线程用法总结
1.多线程的理解 在操作系统中线程和进程划分. 操作系统可以同时执行多个任务,每个任务就是进程:进程可以同时执行多个任务,每个任务就是线程. 线程之间相互独立,抢占式执行.对于单核CPU来说同一时刻只 ...
- 通过编写聊天程序来熟悉python中多线程及socket的用法
1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...
- Java 中 synchronized的用法详解(四种用法)
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...
- Python爬虫进阶五之多线程的用法
前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread ...
- java成神之——java中string的用法
java中String的用法 String基本用法 String分割 String拼接 String截取 String换行符和format格式化 String反转字符串和去除空白字符 String获取 ...
- java中stringBuilder的用法
java中stringBuilder的用法 String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需 ...
- Delphi 中多线程同步的一些处理方法
Delphi 中多线程同步的一些处理方法 当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- C#中string.format用法详解
C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...
- SQL中distinct的用法
SQL中distinct的用法 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
随机推荐
- 2020-12-22:使用MQ的缺陷有哪些?
福哥答案2020-12-22:系统可用性降低:以前只要担心系统的问题,现在还要考虑 MQ 挂掉的问题,MQ 挂掉,所关联的系统都会无法提供服务.系统复杂性变高:要考虑消息丢失.消息重复消费.消息顺序性 ...
- 2022-05-18:假设数组a和数组b为两组信号: 1) length(b) <= length(a); 2) 对于任意0<=i<length(b), 有b[i+1] - b[i] == a[i+1
2022-05-18:假设数组a和数组b为两组信号: length(b) <= length(a): 对于任意0<=i<length(b), 有b[i+1] - b[i] == a[ ...
- Jenkins - 安装部署
Jenkins安装部署 简介 Jenkins是一个开源的软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作,提供一个开放易用的软件平台,使软件的持续集成变成可能. 主要用于: 持续 ...
- python 之路,Django rest framework 初探
摘自 金角大王 https://www.cnblogs.com/alex3714/articles/7131523.html Django rest framework介绍 Django REST ...
- Java(命令行传参、可变参数、递归
1.命令行传参 通过命令行传参,main也可以传参 public class Hello { public static void main(String[] args) { for (int i = ...
- THM红队基础
Red Team Fundamentals Learn the core components of a red team engagement, from threat intelligence t ...
- C#设计模式19——装饰器模式的写法
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码. What(什么) 装饰器模式是一种结构型设计模式,它允许 ...
- 深入解析React DnD拖拽原理,轻松掌握拖放技巧!
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值.. 本文作者:霁明 一.背景 1.业务背景 业务中会有一些需要实现拖拽 ...
- 前端仿京东、天猫带搜索历史搜索栏搜索框searchBar
快速实现前端仿京东.天猫带搜索历史搜索栏搜索框searchBar, 使用简单便利, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12529 ...
- node使用jsonwebtoken生成token与验证是否过期
场景 我们可以使用 cookie,session,token 来做鉴权. 下面我们来看一下, 如何使用 token 来做鉴权 jwt.sign 的简单介绍 npm install jsonwebtok ...