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