上一篇:异步多线程之入Task
下一篇:使用中常见问题,待更新
简介
Parallel 叫做并行编程 .Net 4.5 时代的,基于 Task 基础上做了封装。Parallel 的特点方便控制线程并发数量与节省一个线程。
API
Parallel 相对来说也比较简单,这里介绍几个 API(Invoke、For、ForEach)的用法,这三个 API 都可以节约一个线程。
Invoke
例如:Invoke 方法可以做并发,传入委托即可。这里并发 3 任务,如下
public static void Coding(string name, string module)
{
Console.WriteLine($"{name} Coding Start {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"{name} Coding End {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
}
static void Main(string[] args)
{
Console.WriteLine($"Main Start,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Parallel.Invoke(() => Coding("张三", "Web"), () => Coding("李四", "Service"), () => Coding("王五", "SQL"));
Console.WriteLine($"Main End,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.ReadLine();
}
启动程序,可以看到 3 个任务并发执行,会卡界面。但只有三个线程(1-主线程,3、4-子线程),节约一个线程。
For
For 也是一样的,主线程参与计算,节约一个线程。
public static void Coding(string name, string module)
{
Console.WriteLine($"{name} Coding Start {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"{name} Coding End {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
}
static void Main(string[] args)
{
Console.WriteLine($"Main Start,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Parallel.For(0, 5, i =>
{
Coding("张三"+ i.ToString(), "Web" + i.ToString());
});
Console.WriteLine($"Main End,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.ReadLine();
}
ForEach
For 也是一样的,主线程参与计算,节约一个线程。
public static void Coding(string name, string module)
{
Console.WriteLine($"{name} Coding Start {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"{name} Coding End {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
}
static void Main(string[] args)
{
Console.WriteLine($"Main Start,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Parallel.ForEach(new int[] { 2, 4, 6, 8 }, i =>
{
Coding("张三" + i.ToString(), "Web" + i.ToString());
});
Console.WriteLine($"Main End,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.ReadLine();
}
限定线程数量
Parallel 限定线程数量也是比较简单的,使用 ParallelOptions 设置一下即可。如下
public static void Coding(string name, string module)
{
Console.WriteLine($"{name} Coding Start {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"{name} Coding End {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
}
static void Main(string[] args)
{
Console.WriteLine($"Main Start,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 3;
Parallel.For(0, 10, parallelOptions, i =>
{
Coding("张三" + i.ToString(), "Web" + i.ToString());
});
Console.WriteLine($"Main End,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.ReadLine();
}
如何不卡线程?答案:还是老套路,包一层。如下
public static void Coding(string name, string module)
{
Console.WriteLine($"{name} Coding Start {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.WriteLine($"{name} Coding End {module},ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
}
static void Main(string[] args)
{
Console.WriteLine($"Main Start,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Task.Run(() =>
{
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 3;
Parallel.For(0, 10, parallelOptions, i =>
{
Coding("张三" + i.ToString(), "Web" + i.ToString());
});
});
Console.WriteLine($"Main End,ThreadId:{Thread.CurrentThread.ManagedThreadId},Datetime:{DateTime.Now.ToLongTimeString()}");
Console.ReadLine();
}