c#多线程和并行使用的几种方式
多线程并行执行
线程相对于进程是轻量级,但开销还是很大的,要合理使用线程,一定要避免线程太多,造成线程上下文开销很大,从而影响程序的性能. 人都是有惰性,这篇本来应该在年前写的,当时在家过年,当时没事,写个代码.在macOS,所以是用mono编译的.
多线程并行 所需的方法
/// <summary>
/// Thread1函数 线程执行的方法
/// </summary>
static void Thread1Method(object state)
{
Console.WriteLine($"state={state}");
Thread.Sleep(10000); //休眠10秒钟
}
/// <summary>
/// 用来task任务是否取消
/// </summary>
static void Count(CancellationToken ct, int count)
{
for (int i = 0; i < count; i++)
{
if (ct.IsCancellationRequested)
{
Console.WriteLine("count is cancel!");
break;
}
Console.WriteLine(i);
Thread.Sleep(200);
}
Console.WriteLine("count is done!");
}
/// <summary>
/// 用来测试多线程的方法 求和
/// </summary>
static int Sum(int n)
{
int sum = 0;
for (; n > 0; n--)
{
checked
{
sum += n;
}
}
return sum;
}
常用的几种方式
/// <summary>
/// 线程测试方法1
/// </summary>
public static void Thread1(int state)
{
Thread t1 = new Thread(Thread1Method);
t1.Start(state); //参数通过start方法传入
}
/// <summary>
/// 线程测试方法2 前后台线程
/// </summary>
public static void Thread2()
{
//前台线程
Thread t1 = new Thread(() =>
{
Console.WriteLine("前台线程");
Thread.Sleep(1000);
});
//t1.IsBackground = true; //通过isBackground属性设置为前后台属性,前后台线程可以相互转换
t1.Start();
//t1.Join();
Thread t2 = new Thread(() =>
{
Console.WriteLine("后台线程");
});
t2.IsBackground = true;
t2.Start();
//结论:如果是后台线程就立即结束,如果是前台线程就等执行结束才结束进程
}
/// <summary>
/// 线程测试方法3 使用线程池
/// </summary>
public static void Thread3()
{
//计算简单的任务,不知道任务什么时候完成,一旦开始执行无法取消该任务
ThreadPool.QueueUserWorkItem((state) =>
{
Console.WriteLine($"state={state}");
}, 5);
}
/// <summary>
/// 线程测试方法4 协作式取消
/// </summary>
public static void Thread4()
{
CancellationToken ct = new CancellationToken();
ThreadPool.QueueUserWorkItem((state) => Count(ct, 1000));
}
/// <summary>
/// 测试线程方法5 使用Task
/// </summary>
public static void Thread5()
{
Task<int> task = new Task<int>(n => Sum((int)n), 10000);
task.Start();
task.Wait(100000);
Console.WriteLine($"sum={task.Result}");
}
/// <summary>
/// 测试线程方法6 协作式取消任务 异常处理
/// </summary>
public static void Thread6()
{
CancellationTokenSource cts = new CancellationTokenSource();
Task<int> task = new Task<int>(n => Sum((int)n), 1000, cts.Token);
task.Start();
cts.Cancel(); //取消之后
try
{
Console.WriteLine($"result={task.Result}"); //会报InnerException
}
catch (AggregateException ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 一个任务结束执行下一个任务 用continuewith执行下一个任务
/// </summary>
public static void Thread7()
{
Task<int> task = new Task<int>(n => Sum((int)n), 10000);
task.Start();
Task cwt = task.ContinueWith((arg) =>
{
Console.WriteLine($"result={arg.Result}");
});
}
秋风
2017-04-04