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#中多线程的用法的更多相关文章

  1. qt中多线程用法总结

    1.多线程的理解 在操作系统中线程和进程划分. 操作系统可以同时执行多个任务,每个任务就是进程:进程可以同时执行多个任务,每个任务就是线程. 线程之间相互独立,抢占式执行.对于单核CPU来说同一时刻只 ...

  2. 通过编写聊天程序来熟悉python中多线程及socket的用法

    1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...

  3. Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...

  4. Python爬虫进阶五之多线程的用法

    前言 我们之前写的爬虫都是单个线程的?这怎么够?一旦一个地方卡到不动了,那不就永远等待下去了?为此我们可以使用多线程或者多进程来处理. 首先声明一点! 多线程和多进程是不一样的!一个是 thread ...

  5. java成神之——java中string的用法

    java中String的用法 String基本用法 String分割 String拼接 String截取 String换行符和format格式化 String反转字符串和去除空白字符 String获取 ...

  6. java中stringBuilder的用法

    java中stringBuilder的用法 String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需 ...

  7. Delphi 中多线程同步的一些处理方法

    Delphi 中多线程同步的一些处理方法   当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...

  8. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  9. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  10. SQL中distinct的用法

    SQL中distinct的用法   1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...

随机推荐

  1. 献给转java的c#和java程序员的数据库orm框架

    献给转java的c#和java程序员的数据库orm框架 一个好的程序员不应被语言所束缚,正如我现在开源java的orm框架一样,如果您是一位转java的c#程序员,那么这个框架可以带给你起码没有那么差 ...

  2. WPF入门实例 WPF完整例子 WPF DEMO WPF学习完整例子 WPF实战例子 WPF sql实例应用 WPF资料源码

    WPF 和 WinForms 都是用于创建 Windows 桌面应用程序的开发框架,它们有一些相似之处,但也有很多不同之处. 在开发速度方面,这取决于具体情况.如果您熟悉 WinForms 开发并且正 ...

  3. odoo开发教程十一:视图综述

    一:视图标签等公共结构 name (必选) 用于通过名字查找标签 model: 与view相关联的model priority 当搜索查找view时,优先级最低的view会被返回 arch 视图lay ...

  4. 瞄准程序员招聘痛点,ShowMeBug让面试代码操作可“回放”

    程序员虽然是建设互联网的职业之一,但他们的招聘工作的线上化却有不少难题. 疫情加速了市场对远程办公.远程面试.远程教学等模式的接受程度,但程序员招聘涉及到代码能力测试,甚至不同企业有不同的产品代码基础 ...

  5. 2023 华北分区赛 normal_snake

    国赛终于解出Java题了,顺利拿下一血,思路之前也学过.继续加油 normal_snake 题目解读 @RequestMapping({"/read"}) public Strin ...

  6. C++面试八股文:在C++中,有哪些可执行体?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第14面: 面试官:在C++中,有哪些可执行体? 二师兄:可执行体? 面试官:也就是可调用对象. 二师兄:让我想一想.函数.函数指针.类的静态方法.类 ...

  7. Yolov5代码解析(输入端、BackBone、Neck、输出端))

    [深度学习]总目录 输入端:数据增强.锚框计算等. backbone:进行特征提取.常用的骨干网络有VGG,ResNet,DenseNet,MobileNet,EfficientNet,CSPDark ...

  8. Instruments中常用Template的使用

     Instruments是苹果提供的Xcode套件,可用于分析iOS,MacOS程序的性能数据,进行性能提升.Instruments提供了很多类型的Template,用于特定场景的分析.这里选了3种常 ...

  9. java反射机制原理及应用

    java反射机制 反射机制原理示意图 ​ Class.forName(字节码文件) 类.class 对象.getClass() 用法: 根据配置的properties文件(不仅是properties) ...

  10. 从零实现俄罗斯方块(c语言+思路分析)

    俄罗斯方块 文章说明: 本文大部分参考至俄罗斯方块(C语言实现)_c语言俄罗斯方块_2021dragon的博客-CSDN博客,本人经过修改编辑,改变了文章的一些思路顺序,使得新手便于理解(个人想法). ...