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< string string > funcDelegate = (s) =>
{
     Console.WriteLine( "我是Func委托方法!" );
     return  "委托方法参数:"  + s;
};
 
//1.无阻塞异步回调
var  aysncResult = funcDelegate.BeginInvoke( "这是来自主线程的参数" new  AsyncCallback((result) =>
{
     //获取委托对象,调用EndInvoke方法获取运行结果
     AsyncResult _result = (AsyncResult)result;
     var  func = (Func< string string >)_result.AsyncDelegate;
     string  data = func.EndInvoke(_result);
     Console.WriteLine(data + ",附加参数:"  + _result.AsyncState.ToString());
}), "其它参数" );
 
//2.阻塞主线程,使主线程等待执行完毕
string  data2 =  null ;
var  aysncResult2 = funcDelegate.BeginInvoke( "这是来自主线程的参数2" null null );
 
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)多线程开发基础

本文转自 梦在旅途 博客园博客,原文链接:http://www.cnblogs.com/zuowj/p/4900468.html  ,如需转载请自行联系原作者

相关文章
|
20天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
|
3天前
|
C#
C#同步异步详解
C#同步异步详解
7 0
|
3天前
|
安全 Java C#
C#多线程详解
C#多线程详解
12 0
|
9天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
32 3
|
11天前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
11天前
|
存储 安全 Java
【亮剑】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能
【4月更文挑战第30天】`ConcurrentHashMap`是Java中线程安全的哈希表,采用锁定分离技术提高并发性能。数据被分割成多个Segment,每个拥有独立锁,允许多线程并发访问不同Segment。当写操作发生时,计算键的哈希值定位Segment并获取其锁;读操作通常无需锁定。内部会根据负载动态调整Segment,减少锁竞争。虽然使用不公平锁,但Java 8及以上版本提供了公平锁选项。理解其工作原理对开发高性能并发应用至关重要。
|
17天前
|
缓存 Java 编译器
第一章 Java线程池技术应用
第一章 Java线程池技术应用
18 0
|
17天前
|
并行计算 算法 安全
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
Java从入门到精通:2.1.3深入学习Java核心技术——掌握Java多线程编程
|
18天前
|
并行计算 算法 Java
Java中的多线程技术实现与应用
【4月更文挑战第23天】本文将深入探讨Java中的多线程技术,包括其基本概念、实现方法以及在实际应用中的优势。我们将通过实例代码和应用场景,详细解析多线程技术在Java中的应用,以期帮助读者更好地理解和掌握这一技术。
|
19天前
|
Java
Java中的多线程技术实现
【4月更文挑战第22天】本文将深入探讨Java中的多线程技术实现,包括线程的创建、启动、同步和通信等方面。通过实例分析,我们将了解如何利用多线程提高程序的性能和效率。
9 2