C#线程处理

  C#支持经过多线程并行地执行代码,一个线程有它独立的执行路径,可以与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操做系统(也称为“主线程”)自动建立的,并具备多线程建立额外的线程。
  除非被指定,不然全部的例子都假定如下命名空间被引用了:git

using System;
using System.Threading;

C#开启线程的方法有:github

  • 异步委托
  • 经过Thread类
  • 线程池
  • 任务

  总的来讲其实线程的开启基本都涉及到委托的使用。c#

1、异步委托开启线程

首先来看一个比较简单的例子,采用第一种开启线程的方法——异步委托多线程

using System;
using System.Threading;

namespace Study
{
    class Program
    {
        static void test()
        {
            Console.WriteLine("TestThread");
        }
        static void Main(string[] args)
        {
            Action a = test;
            a.BeginInvoke(null, null);
            Console.WriteLine("MainThread");
            Console.ReadLine();
        }
    }
}

  编译运行,发现结果与预期有所不一样。结果以下图
Thread
  若是按着逐行运行代码的方式,那么应该是先输出TestThread,可是结果倒是先输出MainThread。
  将a.BeginInvoke(null,null);Console.WriteLine("MainThread");对调位置以后,结果和以前的依然一致。这就说明,异步委托开启的线程是和主线程同时同步进行的。
  Action委托是指向一个没有返回值的函数,那么假设一个线程,咱们须要取得他的返回结果并输出,那么就要用到Func委托。
  看下面的源码异步

using System;
using System.Threading;

namespace SummerStudy
{
    class Program
    {
        static string test(int i, string str)
        {
            Console.WriteLine("TestThread" + "\t参数i是:" + i);
            return str;
        }
        static void Main(string[] args)
        {
            Func<int, string, string> a = test;
            IAsyncResult res = a.BeginInvoke(1, "返回值", null, null);
            string o = a.EndInvoke(res);
            Console.WriteLine("MainThread\t" + "线程返回值是:" + o);
            Console.ReadLine();
        }
}

Thread
同时异步委托开启线程中,判断线程是否结束的方法也有两种,一种是利用IAsyncResult的IsCompleted方法,一种是使用方法进行线程结束判断。
  具体使用方法以下。函数

  1. IsCompleted(bool)
IAsyncResult ia = a.BeginInvoke()
if(ia.IsCompleted == false)
{
    //GoOn
}
  1. AsyncWaitHandle
IAsyncResult ia = a.BeginInvoke()
ia.AsyncWaitHandle.WaitOne(Time);//Time为等待时间,超时后才会运行下一行代码,未完成直接跳出返回false

  或者经过自定义方法,BeginInvoke中倒数第二个参数是一个委托,传递一个函数,在线程结束以后会自动的调用。spa

static string Test(int a)
{

}
Func<int, string> a = Test;
IAsyncResult ia = a.BeginInvoke(100, CallBack, a);
static void CallBack(IAsyncResult ar)
{
    Func<int, string> a = ia.AsyncState as Func<int, string>;
    string res = a.EndInvoke(ar);
}

  在使用Lambda表达式做为委托的时候,最后一个参数能够为空,由于Lambda表达式能够访问外部变量。操作系统

2、使用Thread类开启线程

  使用Thread类建立一个实例,它的构造方法中须要传递一个委托。经过委托绑定线程。
  直接上代码线程

using System;
using System.Threading;

namespace Study
{
    class Program
    {
        static void test()
        {
            Console.WriteLine("Thread");
            Thread.Sleep(2000);
            Console.WriteLine("TimeOver");
        }
        static void Main(string[] args)
        {
            Thread t = new Thread(test);
            t.Start();
            Console.WriteLine("Main");
            Console.Read();
        }
    }
}

Thread
  对于须要传递参数的委托,则必须制定参数类型为object,在线程Start方法中传递参数code

namespace SummerStudy
{
    class Program
    {
        static void test(object c)
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Thread,\t线程id为" + id + ",\t参数是:" + c);
            Thread.Sleep(2000);
            Console.WriteLine("TimeOver");

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(test);
            t.Start("xxx.avi");
            Console.WriteLine("Main");
            Console.Read();
        }
    }
}

Thread
  固然你也能够自定义一个类,在类中自定义数据传递。

3、线程池

  这种方法有助于节省时间,具体使用方法以下

using System;
using System.Threading;

namespace SummerStudy
{
    class Program
    {
        static void test(object c)
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Thread,\t线程id为" + id + ",\t参数是:" + c);
            Thread.Sleep(2000);
            Console.WriteLine("TimeOver");

        }
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(test, "asfasf");
            Console.Read();
        }
    }
}

  其中委托必需要有一个参数,不管是否使用该参数。且只适用于使用时间短的线程,不能改变优先级

4、任务

  使用Task类开启线程,还有TaskFactory建立
  Task类实例

using System;
using System.Threading;
using System.Threading.Tasks;

namespace SummerStudy
{
    class Program
    {
        static void test(object c)
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Thread,\t线程id为" + id);
            Thread.Sleep(2000);
            Console.WriteLine("TimeOver");

        }
        static void Main(string[] args)
        {
            Task t = new Task(test, "Asfgasg");
            t.Start();

            //或者

            TaskFactory tf = new TaskFactory();

            Task t1 = tf.StartNew(test);
            Console.Read();
        }
    }
}

个人掘金:WarrenRyan

个人简书:WarrenRyan

欢迎关注个人博客得到第一时间更新 https://blog.tity.xyz

个人Github:WarrenRyan

个人博客园:WarrenRyan

相关文章
相关标签/搜索