C#语法基础-04-线程

6 篇文章 0 订阅

C#语法基础-04-线程

写这两篇文章的目的是为了备忘、 C#语言在大学读书时候学过、当时做过一些东西、但是由于从事的主要工作和C#无关便忘记了。 近来公司增加了Unity业务、 写Unity主要是C# 和js 想来C# 的语法结构和Java很相似、于是采用了C#语言作为公司游戏项目的主要语言。

本系列主要分上中下三篇文章来记录。 分别牵涉到C# 中的初级、中级、高级内容。

由于本月一直忙于公司的项目、 所以发文就耽搁了, 但是回想五月忙上过去了,还是整理整理发一篇吧。

本文主要写一些关于C#语言的高级知识, 如果没有看过初级的,可以先看上一篇文章,在电脑上敲敲试试,跑一下看看。

  1. 委托方式发起线程

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+"在回调函数中取得结果");
        }
    }
}

  1. 通过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();
        }
    }
}

  1. 总结

还是那句话、多思考、上手敲代码、 调试调试、多试试。 如果有问题可以评论区留言共同学习进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值