C#语法基础-04-线程
写这两篇文章的目的是为了备忘、 C#语言在大学读书时候学过、当时做过一些东西、但是由于从事的主要工作和C#无关便忘记了。 近来公司增加了Unity业务、 写Unity主要是C# 和js 想来C# 的语法结构和Java很相似、于是采用了C#语言作为公司游戏项目的主要语言。
本系列主要分上中下三篇文章来记录。 分别牵涉到C# 中的初级、中级、高级内容。
由于本月一直忙于公司的项目、 所以发文就耽搁了, 但是回想五月忙上过去了,还是整理整理发一篇吧。
本文主要写一些关于C#语言的高级知识, 如果没有看过初级的,可以先看上一篇文章,在电脑上敲敲试试,跑一下看看。
- 委托方式发起线程
namespace _01_线程_委托方式发起线程 {
class Program {
//一般我们会为比较耗时的操作 开启单独的线程去执行,比如下载操作
static int Test(int i,string str)
{
Console.WriteLine("test"+i+str);
Thread.Sleep(100);//让当亲线程休眠(暂停线程的执行) 单位ms
return 100;
}
static void Main(string[] args) {//在main线程中执行 一个线程里面语句的执行 是从上到下的
//1,通过委托 开启一个线程
//Func<int, string, int> a = Test;
//IAsyncResult ar = a.BeginInvoke(100, "siki", null, null);// 开启一个新的线程去执行 a所引用的方法
IAsyncResult 可以取得当前线程的状态
可以认为线程是同时执行的(异步执行)
//Console.WriteLine("main");
//while (ar.IsCompleted == false)//如果当前线程没有执行完毕
//{
// Console.Write(".");
// Thread.Sleep(10); //控制子线程的检测频率
//}
//int res = a.EndInvoke(ar);//取得异步线程的返回值
//Console.WriteLine(res);
//检测线程结束
//bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);
//1000毫秒表示超时时间,如果等待了1000毫秒 线程还没有结束的话 那么这个方法会返回false 如果在1000毫秒以内线程结束了,那么这个方法会返回true
//if (isEnd)
//{
// int res = a.EndInvoke(ar);
// Console.WriteLine(res);
//}
//通过回调 检测线程结束
//Func<int, string, int> a = Test;
//倒数第二个参数是一个委托类型的参数,表示回调函数,就是当线程结束的时候会调用这个委托指向的方法 倒数第一个参数用来给回调函数传递数据
//IAsyncResult ar = a.BeginInvoke(100, "siki", OnCallBack, a);// 开启一个新的线程去执行 a所引用的方法
//a.BeginInvoke(100, "siki", ar =>
//{
// int res = a.EndInvoke(ar);
// Console.WriteLine(res+"在lambda表达式中取得");
//}, null);
Console.ReadKey();
}
static void OnCallBack( IAsyncResult ar )
{
Func<int, string, int> a = ar.AsyncState as Func<int, string, int>;
int res = a.EndInvoke(ar);
Console.WriteLine(res+"在回调函数中取得结果");
}
}
}
- 通过Thread发起线程
namespace _02_线程_通过Thread发起线程 {
class Program {
static void DownloadFile(object filename)
{
Console.WriteLine("开始下载:" +Thread.CurrentThread.ManagedThreadId +filename);
Thread.Sleep(2000);
Console.WriteLine("下载完成");
}
static void Main(string[] args) {
//Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动
//t.Start();//开始,开始去执行线程
//Console.WriteLine("Main");
//Thread t = new Thread(() =>
//{
// Console.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId);
// Thread.Sleep(2000);
// Console.WriteLine("下载完成");
//});
//t.Start();
//Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动
//t.Start("xxx.种子");//开始,开始去执行线程
//Console.WriteLine("Main");
//MyThread my = new MyThread("xxx.bt","http://www.xxx.bbs");
//Thread t = new Thread(my.DownFile);//我们构造一个thread对象的时候,可以传递一个静态方法,也可以传递一个对象的普通方法
//t.Start();
//Thread t = new Thread(DownloadFile);//这个是前台线程
Thread t = new Thread(DownloadFile);//这个是前台线程
//t.IsBackground = true;//设置为后台线程
t.Start("xx");
//t.Abort();//终止这个线程的执行
t.Join();//当当前线程睡眠,等待t线程执行完,然后继续运行下面的代码
//
}
}
}
class MyThread
{
private string filename;
private string filepath;
public MyThread(string fileName, string filePath)
{
this.filename = fileName;
this.filepath = filePath;
}
public void DownFile()
{
Console.WriteLine("开始下载"+filepath+filename);
Thread.Sleep(2000);
Console.WriteLine("下载完成");
}
}
3.线程池
namespace _03_线程_线程池 {
class Program {
static void ThreadMethod(object state)
{
Console.WriteLine("线程开始:"+Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("线程结束");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(ThreadMethod);//开启一个工作线程
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
Console.ReadKey();
}
}
}
4.线程任务
namespace _04_线程_任务 {
class Program {
static void ThreadMethod() {
Console.WriteLine("任务开始");
Thread.Sleep(2000);
Console.WriteLine("任务结束");
}
static void Main(string[] args) {
//Task t = new Task(ThreadMethod);//传递一个需要线程去执行的方法
//t.Start();
//TaskFactory tf = new TaskFactory();
//Task t = tf.StartNew(ThreadMethod);
Console.WriteLine("Main");
Console.ReadKey();
}
}
}
5.线程争用问题
namespace _05_线程问题_争用条件 {
class Program {
static void ChangeState(object o)
{
MyThreadObject m = o as MyThreadObject;
while (true)
{
lock (m)//向系统申请可不可以 锁定m对象 如果m对象没有被锁定,那么可以 如果m对象呗锁定了,那么这个语句会暂停,知道申请到m对象
{
m.ChangeState();//在同一时刻 只有一个线程在执行这个方法
}//释放对m的锁定
}
}
static void Main(string[] args) {
MyThreadObject m = new MyThreadObject();
Thread t = new Thread(ChangeState);
t.Start(m);
new Thread(ChangeState).Start(m);
Console.ReadKey();
}
}
}
- 总结
还是那句话、多思考、上手敲代码、 调试调试、多试试。 如果有问题可以评论区留言共同学习进步。