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. 2022-07-10:以下go语言代码输出什么?A:A,B;B:A,C:A,fatal error;D:fatal error... func main() { var m sync.Mute

    2022-07-10:以下go语言代码输出什么?A:A,B:B:A,C:A,fatal error:D:fatal error- func main() { var m sync.Mutex fmt. ...

  2. 2021-01-10:linux中,我要看某一个进程的并发,通过什么命令去查?

    福哥答案2021-01-10:[答案来自此链接:](https://blog.csdn.net/sinat_31275315/article/details/108239492)方法一:PS在ps命令 ...

  3. 2021-01-09:linux中,某一个实时日志通过什么命令查?

    福哥答案2020-01-09:[答案来自此链接:](https://www.zhihu.com/question/438536200)1.tailtail -f首先就是 tail -f,tail 命令 ...

  4. 2021-03-31:给定一个数组arr,给定一个值v。求子数组平均值小于等于v的最长子数组长度。

    2021-03-31:给定一个数组arr,给定一个值v.求子数组平均值小于等于v的最长子数组长度. 福大大 答案2021-03-31: 这道题是昨天每日一题的变种.数组每个元素减v,然后求<=0 ...

  5. ESLint: More than 1 blank line not allowed. (no-multiple-empty-lines)

    ESLint: More than 1 blank line not allowed. (no-multiple-empty-lines)

  6. C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)

    信创是现阶段国家发展的重要战略之一,面对这一趋势,所有的软件应用只有支持信创国产化的基础软硬件设施,在未来才不会被淘汰.那么,如何可以使用C#来实现支持信创环境的视频会议系统吗?答案是肯定的. 本文讲 ...

  7. java开发学习框架

    Java基础 1.1. Java简介与安装 1.2. Java基本语法 1.3. 数据类型与变量 1.4. 运算符与表达式 1.5. 流程控制(分支与循环) 1.6. 数组 面向对象编程 2.1. 类 ...

  8. ARC144

    ARC 144 比赛情况:一眼订正,鉴定为做起 \(3\) 道题. A - Digit Sum of 2x \(2x\) 进位就不满足 \(M\) 最大的条件了,所以 \(x\) 不能进位. 然后要求 ...

  9. Python自动化测试面试题精选(一)

    Python自动化测试面试题精选 今天由勇哥给你介绍一些Python自动化测试中常见的面试题,涵盖了Python基础.测试框架.测试工具.测试方法等方面的内容,希望能够帮助你提升自己的水平和信心. 项 ...

  10. 记录一个在写项目中遇到的Maven依赖无法导入的问题

    记录一个在写项目中遇到的Maven依赖无法导入的问题 项目是一个父项目做依赖管理,三个子项目,今天遇到一个问题: 子项目中导入的依赖,怎么都导入不进去,maven仓库中已经有了,idea提示也没有问题 ...