C#多线程技术总结(异步)

我这里针对现有的C#多线程技术进行一个汇总,一是复习,二是方便索引,文章部份知识点来源于网络,非本人原创。

一、并行(异步):

1.System.Threading.Tasks命名空间下的(TPL):

1.1:Parallel.Invoke --并行执行多个任务,主线程等待并行执行完毕后才开始续续运行。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void Main(string[] args)
{
    Parallel.Invoke(new ParallelOptions() { MaxDegreeOfParallelism=2},Run1,Run2);
    Console.WriteLine("我是主线程!");
    Console.Read();
}
static void Run1()
{
    Console.WriteLine("我是任务一,我运行3s");
    Thread.Sleep(3000);
    Console.WriteLine("任务一执先完成");
}
static void Run2()
{
    Console.WriteLine("我是任务二,我运行5s");
    Thread.Sleep(5000);
    Console.WriteLine("任务二执先完成");
}

1.2:Parallel.For--循环迭代多个任务,多个任务之间存在并行情况,主线程等待循环迭代的多个任务执行完毕后才开始续续运行。

示例:

1
2
3
4
5
Parallel.For(0, 10, (i) => {
                Console.WriteLine("我是第{0}个任务,线程ID是:{1}",i,Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(new Random().Next(10) * 10 * 500);
                Console.WriteLine("线程ID是:{0}执行完成", Thread.CurrentThread.ManagedThreadId);
            });

1.3:Parallel.ForEach--循环迭代多个任务,多个任务之间存在并行情况,主线程等待循环迭代的多个任务执行完毕后才开始续续运行。注意它有多个重载方法

示例:

1
2
3
4
5
6
7
8
9
10
11
var bag = new ConcurrentBag<int>();
Parallel.ForEach(Partitioner.Create(0, 100), i =>
{
    for (int m = i.Item1; m < i.Item2; m++)
    {
        bag.Add(m);
        Console.WriteLine("我是第{0}个任务,线程ID是:{1}", m, Thread.CurrentThread.ManagedThreadId);
    }
});
Console.WriteLine("并行计算:集合有:{0}", bag.Count);

1.4:TAP(基于任务的异步编),使用Task类 (注意:默认任务开启后,会在新线程中执行,主线程不会等待任务而是继续下面的执行,若使用Task.WaitAll,则会等待相应的任务完成后才会执行)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//第一种方式启动
var task1 = new Task(() => //实例化
            {
                Run1();
            });
task1.Start(); //启动
 //第二种方式开启
 var task2 = Task.Factory.StartNew(() => //直接创建任务并启动
            {
                Run2();
            });
//主线程等待任务执行完
 Task.WaitAll(task1, task2);

2.ParallelEnumerable类中的扩展方法(先将枚举对象使用AsParallel转换成ParallelQuery类型,然后就可以使用ParallelQuery在ParallelEnumerable类相关的扩展方法)

示例:

1
2
var resultList = testList.AsParallel().Where(i=>i>=100).ToList();
 Console.WriteLine("resultList Count:{0}", resultList.Count);

3.创建新Thread--新线程启动后,主线程与创建的线程各自执行,若需要主线程等待异步线程执行完成后才执行,则应使用asyncThread.Join方法。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        static void AsyncThreadMethod()
        {
            Console.WriteLine("我是异步执行线程,线程ID是:{0}", Thread.CurrentThread.ManagedThreadId);
        }
        static void AsyncThreadMethod(object state)
        {
            Console.WriteLine("我是异步执行线程,线程ID是:{0},状态:{1}", Thread.CurrentThread.ManagedThreadId,state);
        }
//创建线程并执行
            Thread asyncThread = new Thread(new ThreadStart(AsyncThreadMethod));
            asyncThread.IsBackground = true;
            asyncThread.Start();
            Thread asyncThread2 = new Thread(new ParameterizedThreadStart(AsyncThreadMethod));
            asyncThread2.IsBackground = true;
            asyncThread2.Start("这是来自主线程的参数");

4.使用ThreadPool.QueueUserWorkItem静态方法--WaitCallback回调方法要求其必需带一个object的参数

示例:

1
2
3
ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncThreadMethod));//不带参数,则系统将state自动设为null
ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncThreadMethod), "这是来自主线程的参数");

5.APM(异步编程模型),利用BeginInvoke与EndInvoke完成异步执行委托方法

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Func<stringstring> funcDelegate = (s) =>
{
    Console.WriteLine("我是Func委托方法!");
    return "委托方法参数:" + s;
};
//1.无阻塞异步回调
var aysncResult = funcDelegate.BeginInvoke("这是来自主线程的参数"new AsyncCallback((result) =>
{
    //获取委托对象,调用EndInvoke方法获取运行结果
    AsyncResult _result = (AsyncResult)result;
    var func = (Func<stringstring>)_result.AsyncDelegate;
    string data = func.EndInvoke(_result);
    Console.WriteLine(data +",附加参数:" + _result.AsyncState.ToString());
}),"其它参数");
//2.阻塞主线程,使主线程等待执行完毕
string data2 = null;
var aysncResult2 = funcDelegate.BeginInvoke("这是来自主线程的参数2"nullnull);
data2 = funcDelegate.EndInvoke(aysncResult2);//第一种阻塞方法
while (!aysncResult2.IsCompleted) //第二种阻塞方法
{
    Thread.Sleep(200);      //虚拟操作
    Console.WriteLine("主线程等待...");
}
data2 = funcDelegate.EndInvoke(aysncResult2);
WaitHandle[] waitHandles = new WaitHandle[]{ aysncResult2.AsyncWaitHandle };
while (WaitHandle.WaitAll(waitHandles, 5000)) //第三种阻塞方法
{
    Console.WriteLine("主线程等待...");
}

6. EAP(基于事件的异步编程)--主要用在客户端应用程序中

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//例子一
var client = new WebClient();
client.DownloadProgressChanged += delegate(object s, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("Download Percent:{0}", e.ProgressPercentage);
};
client.DownloadStringCompleted += delegate(object s,DownloadStringCompletedEventArgs e){
    Console.WriteLine("Download Content Length:{0}",e.Result.Length);
    Console.WriteLine("Download Completed!");
};
client.DownloadStringAsync(new Uri("http://www.zuowenjun.cn"));
//例子二
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) => {
    Console.WriteLine("异步执行中。。。");
};
worker.RunWorkerCompleted += (s, e) => {
    Console.WriteLine("异步执行完成。。。");
};
worker.RunWorkerAsync();

7.async和await关键字

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    public Task<double> GetValueAsync(double num1, double num2)
    {
        return Task.Run(() =>
        {
            for (int i = 0; i < 1000000; i++)
            {
                num1 = num1 / num2;
            }
            return num1;
        });
    }
    public async void DisplayValue()
    {
        double result = await GetValueAsync(1234.5, 1.01);//此处会开新线程处理GetValueAsync任务,然后方法马上返回
        //这之后的所有代码都会被封装成委托,在GetValueAsync任务完成时调用
        System.Diagnostics.Debug.WriteLine("Value is : " + result);
    }
//调用
DisplayValue();//不会阻塞主线程

 参考以下相关文章:

C#综合揭秘——细说多线程(上)

C#综合揭秘——细说多线程(下)

8天玩转并行开发系列文章

.NET基础拾遗(5)多线程开发基础

转载于:https://www.cnblogs.com/wzg168/p/8559500.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hutool的定时任务不支持依赖注入怎么办_设计一个任务调度算法,时间轮算法,比优先队列更高效...

当年我还是个学生的时候&#xff0c;有一次去参加欢聚时代的一个面试&#xff0c;有一道面试题记忆尤新&#xff0c;让你来实现一个定时任务&#xff0c;你会怎么做&#xff1f;为了简化问题&#xff0c;我们只用考虑内存方案&#xff0c;不用考虑数据持久化。数组法最简单的&a…

蜂鸟开发板 linux,蜂鸟E203系列——Linux下运行hello world例程

创建程序在 &#xff5e;/hbird-e-sdk-master/software 路径下创建一个“helloworld”中文件夹在 &#xff5e;/hbird-e-sdk-master/software/helloworld 路径下创建文件“helloworld.c”内容如下&#xff1a;#includeint main(void){printf("hello world!");printf(…

全景解密量子信息技术:高层集中学习,国家战略,三大领域一文看懂

来源&#xff1a;智东西 内参来源&#xff1a;中国信通院 IPRdaily中文网10月16日下午&#xff0c;高层就量子科技研究相关前景举行了一次会议&#xff0c;强调当今世界正经历百年未有之大变局&#xff0c;科技创新是其中一个关键变量。要充分认识推动量子科技发展的重要性&am…

shell 脚本编写 if else then

shell 脚本编写 if else then if ....; then .... elif ....; then .... else .... fi 大多数情况下&#xff0c;可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…   通常用" [ ] "来表示条件测试。注意这里的空格很重要。…

mac怎么查看gitlab的注册邮箱_163电子邮箱怎么注册申请?手机号注册电子邮箱的小技巧...

电子邮箱帮助我们实现了无纸化&#xff0c;无需手写信件&#xff0c;通过电脑、手机输入&#xff0c;即可与收件人在网络上进行联系。电子邮箱的兴起&#xff0c;对于人与人之间的沟通和交流&#xff0c;增加了便捷性&#xff0c;促进了社会的发展与进步。目前的邮箱中&#xf…

c语言 switch案例,c语言switch case语句使用例子

c语言switch case语句使用例子发布时间&#xff1a;2020-04-23 11:48:53来源&#xff1a;亿速云阅读&#xff1a;421作者&#xff1a;小新这篇文章主要为大家详细介绍了c语言switch case语句使用例子&#xff0c;文中示例代码介绍的非常详细&#xff0c;具有一定的参考价值&…

把手机上的新浪微博客户端卸载了

因为我本身发微博的时候就是通过通过电脑上的浏览器发的&#xff0c;就连看别人发的微博也是通过浏览器发的&#xff0c;基本上也不怎么用手机客户端。反而是客户端总是推送各种新闻&#xff0c;我实在是没有这个需要&#xff0c;也完全不想被弹窗影响。 综上所述&#xff0c;因…

深度学习未来的三种方式

来源&#xff1a;海豚数据科学实验室深度学习的未来在于这三种学习模式&#xff0c;而且它们彼此之间密切相关&#xff1a;混合学习——现代深度学习方法如何跨越监督学习和非监督学习之间的边界&#xff0c;以适应大量未使用的无标签数据&#xff1f;复合学习——如何以创造性…

c 语言sort函数,C/c++语言sort函数如何使用

头文件是#include比如说数组a[5]{1,5,4,2,3};当你用sort(a,a5)时&#xff0c;就把数组a从小到大排序了for(i0;i<5;i){printf("%d \n",a[i]);}输出为1 2 3 4 5C语言中没有预置的sort函数。如果在C语言中&#xff0c;遇到有调用sort函数&#xff0c;就是自定义的一个…

android ocr识别源码_身份证识别OCR解决手动输入繁琐问题

随着互联网金融的的发展&#xff0c;越来越多的互联网金融公司都推出了自己的金融APP&#xff0c;这些APP都涉及到个人身份证信息的输入认证&#xff0c;如果手动去输入身份证号码和姓名&#xff0c;速度非常慢&#xff0c;且用户体验非常差。为了提高在手机移动终端上输入身份…

mybatis异常invalid comparison: java.util.Date and java.lang.String

原文链接&#xff1a;http://blog.csdn.net/wanghailong_qd/article/details/50673144 mybatis异常invalid comparison: java.util.Date and java.lang.String 开发中改动mapper文件后需要重新编译发布, 由于工程比较大非常耗时, 所以为方便快速测试干脆写了一个小java工程. 工…

计算机c语言等级考试PDF,国家计算机等级考试c语言精华.pdf

心之所向&#xff0c;所向披靡C 语言总复习顺序结构程序设计1.单字符输入输出&#xff1a;getchar(字符变量) &#xff1b;putchar(字符变量) &#xff1b;2.字符串输入输出&#xff1a;gets(字符数组名),puts(字符数组名)。3.格式化输入输出&#xff1a;(1)格式化输入&#xf…

什么是内卷?华为内部这篇文章读懂

来源&#xff1a;互联网坊间八卦&#xff08;ID:kekesil&#xff09;内卷的意思是明明已经靠近边界有个天花板&#xff0c;但却又不断自我激发&#xff0c;繁复化、精致化。概念的含糊其辞是无效讨论和跌入焦虑自我再生产困境的原因之一。判断内卷还是良性竞争的前置问题是回答…

锁屏界面显示某些设置已隐藏_iOS 14 隐藏功能,只要轻点手机背面就能截屏

关于 iOS 14 系统的一些功能我也为大家介绍了一些&#xff0c;iOS 14 已发布&#xff0c;界面大更新&#xff01;其实除了之外&#xff0c;iOS 14 系统还有许多隐藏的功能。那么今天我就为大家介绍 iOS 14 系统的隐藏功能之一&#xff1a;轻点背面。话不多说&#xff0c;我们先…

jacascript AJAX 学习

前言&#xff1a;这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方&#xff0c;请大家指正&#xff0c;我会持续更新&#xff01; AJAX 是 asynchronous javascript and XML 的简写&#xff0c;就是异步的 javascript 和 XML。这一技术能够向服务器请求额外的数据而…

android 自定义控件 焦点,android中设置控件获得焦点

android中&#xff0c;要使控件获得焦点&#xff0c;需要先setFocus,再requestFocus。以Button为例&#xff1a;btn.setFocusable(true);btn.setFocusableInTouchMode(true);btn.requestFocus();btn.requestFocusFromTouch();//获得失去焦点的监听器btn.setOnFocusChangeListen…

分享丨强化学习是针对优化数据的监督学习?

来源&#xff1a;AI科技大本营作者 | Ben Eysenbach、Aviral Kumar、Abhishek Gupta 编译 | 凯隐出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;强化学习&#xff08;RL&#xff09;可以从两个不同的视角来看待&#xff1a;优化和动态规划。其中&#xff0c;诸如REI…

stm32l0的停止模式怎么唤醒_手把手教你怎么利用旧电脑搭建NAS组建自己的黑群晖...

手把手教你怎么利用旧电脑搭建NAS组建自己的黑群晖Synology群晖科技&#xff08;Synology &#xff09;创立于 2000 年&#xff0c;自始便专注于打造高效能、可靠、功能丰富且绿色环保的 NAS 服务器&#xff0c;是全球少数几家以单纯的提供网络存储解决方案获得世界认同的华人企…

pat 甲级 1034. Head of a Gang (30)

1034. Head of a Gang (30) 时间限制100 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YueOne way that the police finds the head of a gang is to check peoples phone calls. If there is a phone call between A and B, we say that A and B is relat…

有人说 GPT3 是“暴力美学”的结晶,它的工作原理你知道吗?| 动图详解

来源&#xff1a;CSDN如今&#xff0c;在科技领域掀起了一股GPT3的热潮。大规模语言模型&#xff08;比如GPT3&#xff09;的潜力惊艳了我们。虽然这些模型还没有成熟到大多数企业将之直接面对消费者&#xff0c;但却展示出一些智慧的火花&#xff0c;并让人坚信其将会加速自动…