多线程编程(3、多任务并发处理)

更新时间:2023-06-14 04:18:09 阅读: 评论:0

多线程编程(3、多任务并发处理)例:假设我们有个⽅法要执⾏100次,得到100次返回的结果总和。
串⾏执⾏
static void Main(string[] args)
{
SerialExcute();
Console.ReadLine();
}
/// <summary>家常肉饼
/// 串⾏执⾏,要阻塞主线程,不推荐
/// </summary>
private static void SerialExcute()
{
int sum=0;
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 100; i++)
{
sum += Method(i);
}
watch.Stop();
Console.WriteLine("100次执⾏总共开销{0}毫秒,结果总和为:{1}。", watch.ElapdMilliconds,sum);
Console.WriteLine("这是主线程.");
Console.WriteLine("100次执⾏结束.");
}
private static int Method(int i)
{
Console.WriteLine("这是第{0}次执⾏Method", i);
//睡眠100毫秒秒
Thread.Sleep(100);
return i;
}
100次执⾏总共开销10001毫秒,结果总和为:4950。
线程池并发执⾏
设计思维导图
class Program
{
static void Main(string[] args)
{
TaskExcute();
}
private static object lockobj = new object();
/// <summary>
///  线程池并⾏运⾏,如果出异常捕获不了,将导致整个程序崩溃。(不推荐使⽤)
/// </summary>
private static void TaskExcute()
{
int sum=0;
Stopwatch watch = new Stopwatch();
watch.Start();
try
{
//采⽤计数器来判断线程池⾥的线程全部执⾏完毕
CountdownEvent handler = new CountdownEvent(100);
//ThreadPool.SetMaxThreads(5, 5);
//设置并发数 5
ThreadPool.SetMinThreads(5, 5);
for (int i = 0; i < 100; i++)长焦数码相机
{
var j = i;//这⾥⼀定要定义⼀个新的变量
ThreadPool.QueueUrWorkItem((state) =>
{
int result = Method(j);
//加锁
坐井观天教学反思lock (lockobj)
{
sum += result;
}
handler.Signal();
});
}
///主线程等待
handler.Wait();
}
catch (AggregateException ex)
{
Console.WriteLine(ex.Message);
//4 Task的统⼀异常处理机制
foreach (Exception inner in ex.InnerExceptions)
{
Console.WriteLine("Exception type {0} from {1}",
inner.GetType(), inner.Source);
}
}
watch.Stop();
Console.WriteLine("100次执⾏总共开销{0}毫秒,结果总和为:{1}。", watch.ElapdMilliconds, sum);            Console.WriteLine("这是主线程.");
Console.WriteLine("100次执⾏结束.");
}一个令我敬佩的人
private static int Method(int i)
{
Console.WriteLine("这是第{0}次执⾏Method", i);
//睡眠100毫秒
Thread.Sleep(100);
//  throw new NullReferenceException("测试异常");
return i;
}
}
100次执⾏总共开销1826毫秒,结果总和为:4950。
Task并⾏执⾏
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
class Program
{
static void Main(string[] args)
{
TaskExcute();
}
private static object lockobj = new object();
public static CancellationTokenSource TokenSource = new CancellationTokenSource();
/// <summary>
///  Task并发执⾏,不能⾃定义并发数(不推荐)
/// </summary>
private static void TaskExcute()
{
int sum = 0;
Stopwatch watch = new Stopwatch();
watch.Start();
try
{
List<Task> tasks = new List<Task>();
List<int> results = new List<int>();
for (int i = 0; i < 100; i++)
{
var j = i;
tasks.Add(Task.Factory.StartNew(() =>
{
results.Add(Method(j));
}, TokenSource.Token));
}
Task.WaitAll(tasks.ToArray());
sum = results.Sum();
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
Console.WriteLine(inner.Message);
}
创业孵化}
watch.Stop();
Console.WriteLine("100次执⾏总共开销{0}毫秒,结果总和为:{1}。", watch.ElapdMilliconds, sum);
Console.WriteLine("这是主线程.");
Console.WriteLine("100次执⾏结束.");
}
private static int Method(int i)
{
Console.WriteLine("这是第{0}次执⾏Method", i);
//睡眠100毫秒,将此值调⼤将能开到并发数
Thread.Sleep(100);
try
{
// throw new NullReferenceException("测试异常");
}
catch (Exception ex)
catch (Exception ex)
{
TokenSource.Cancel();
throw ex;
}
return i;
}
}
}
100次执⾏总共开销2218毫秒,结果总和为:4950。
重写任务调度器
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
class Program
{
static void Main(string[] args)
{
TaskExcute();
}
private static object lockobj = new object();
/// <summary>
///  重写任务调度器实现并发执⾏,可以捕获异常且可以⾃定义并发数,推荐使⽤
/// </summary>
private static void TaskExcute()
{
int sum = 0;
Stopwatch watch = new Stopwatch();
watch.Start();
try
{
NTaskScheduler scheduler = new NTaskScheduler(5);
List<Task> tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
var j = i;
tasks.Add(new Task(() =>
{
var result = Method(j, scheduler._tokenSource);
lock (lockobj)
{
sum += result;
}
}, scheduler._tokenSource.Token));
tasks[i].Start(scheduler);
}
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException ex)
{
foreach (var item in ex.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
watch.Stop();
Console.WriteLine("100次执⾏总共开销{0}毫秒,结果总和为:{1}。", watch.ElapdMilliconds, sum);
Console.WriteLine("100次执⾏总共开销{0}毫秒,结果总和为:{1}。", watch.ElapdMilliconds, sum);
Console.WriteLine("这是主线程.");
Console.WriteLine("100次执⾏结束.");
}
private static int Method(int i, CancellationTokenSource TokenSource)
{
Console.WriteLine("这是第{0}次执⾏Method", i);
//睡眠100毫秒,当前时间放⼤可以查看并发数
Thread.Sleep(100);
try
{
// throw new NullReferenceException("测试异常");
}
catch (Exception ex)
{
TokenSource.Cancel();
throw ex;
}
return i;
}
}
}
NTaskScheduler.cs子规啼
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
地羊肉
/// <summary>
/
// ⾃定义并发任务调度
/// </summary>
public class NTaskScheduler : TaskScheduler, IDisposable
{
private CancellationTokenSource TokenSource =null;
public CancellationTokenSource _tokenSource { get {
if (TokenSource == null) TokenSource = new CancellationTokenSource();
return TokenSource;
}
}
private List<Thread> _threads = new List<Thread>();
private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
private int _concurrencylevel;
/// <summary>
/// 初始化并发调度器
/// </summary>
/// <param name="concurrencyLevel">并发数</param>
public NTaskScheduler(int concurrencylevel)
{
this._concurrencylevel = concurrencylevel;
for (int i = 0; i < concurrencylevel; i++)
{
_threads.Add(new Thread(() =>
{
foreach (Task task in _tasks.GetConsumingEnumerable())
this.TryExecuteTask(task);

本文发布于:2023-06-14 04:18:09,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/949827.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:并发   线程   结果   定义   总和   推荐
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图