CSharp 多线程

1.Thread

1.1 基础的,Lambda 与委托,写法灵活,这里不展开

static void Main(string[] args)
{
    Thread thread = new Thread((() =>
    {
        Console.WriteLine ("我被执行了!");
    }));
    thread.Start();
    Console.ReadLine();
}

1.2 使用函数

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(Function);
        thread.Start();
        Console.ReadLine();
    }

    /// <summary>
    /// 执行体
    /// </summary>
    static void Function()
    {
        Console.WriteLine ("我被执行了");
    }
}

1.3 使用函数并且传递参数

执行函数的参数必须为 object, 才能匹配 Thread 的委托签名,使用起来不优雅,使用参数存在强制转换的问题

class Program
{
    static void Main(string[] args)
    {
        Thread thread = new Thread(Function);
        thread.Start ("我是一个参数");
        Console.ReadLine();
    }

    /// <summary>
    /// 执行体
    /// </summary>
    static void Function(object args)
    {
        Console.WriteLine(args);
    }
}

2.Task, 这个内容就稍微有点多了

class Program
{
    static void Main(string[] args)
    {
        // 与 Thread 类似,直接 new
        Task task1 = new Task(Function);
        task1.Start();

        Task task2 = new Task(() =>
                              {
                                  Function ("呵呵哒");
                              });
        task2.Start();
        //------------------------------------------------------------
        // 直接创建并启动
        Task.Factory.StartNew(Function);
        Task.Factory.StartNew(() =>
                              {
                                  Function ("呵呵哒");
                              });
        //------------------------------------------------------------
        // 利用泛型 Task 获取返回值
        Task<int> task3 = Task.Factory.StartNew(GetResult);
        task3 = Task.Run(GetResult);
        task3 = Task.Run(() =>
                         {
                             Console.WriteLine ("做点别的啥的都可以...");
                             return GetResult();
                         });
        // 只有具有返回值得 Task 对象才能获取 Result 属性,这个属性是阻塞的
        // 也就是说如果这个 Task 还没有执行完的话,调用这个属性会等待 Task 执行完成
        var result = task3.Result;


        //------------------------------------------------------------
        // 等待一组 Task / 线程执行完成
        List<Task> tasks = new List<Task>(10);
        for (int i = 0; i < 10; i++)
        {
            var startNew = Task.Factory.StartNew(Function);
            tasks.Add(startNew);
        }

        //------------------------------------------------------------
        // 等待上面创建的 10 个 Task 全部完成,这个方法是阻塞的
        Task.WaitAll(tasks.ToArray());

        //------------------------------------------------------------
        // 等待上面创建的 10 个 Task 中的任意一个完成,这个方法也是阻塞的
        Task.WaitAny(tasks.ToArray());

        // 延续任务,例如:游戏里学技能,某些技能具有前置技能,学了 A 才能学 B.
        // 这里有两个任务,一个 TaskA 一个 TaskB 
        // 一个 TaskB 必须要拿到 TaskA 的返回值才能开始计算,如下
        Task<int> myTask = Task.Run(TaskA).ContinueWith(p =>
                                                        {
                                                            //p.Result 就是 TaskA 这个方法的返回值 
                                                            return TaskB(p.Result);
                                                        });

        // 那么这里两个 Task 执行完成后 结果为 1234567
        Console.WriteLine(myTask.Result);



        //------------------------------------------------------------
        // 获取 / 等待一组任务执行完成,并获取所有返回值
        // 比如:七龙珠集齐召唤神龙,一定要凑齐 7 颗才能继续
        Task<int>[] taskArr =new Task<int>[7];
        for (int i = 0; i < 7; i++)
        {
            taskArr[i] = Task.Factory.StartNew(TaskA);
        }
        // 获取 7 个任务的返回值
        var resultAll = Task.WhenAll(taskArr).Result;

        // 获取 / 等待一组任务的任意一个执行完成,并获取返回值
        // 比如:大地鼠,谁先冒头,先打死谁 (这个比喻有点不恰当)
        var value = Task.WhenAny(taskArr).Result.Result;

    }

    static int TaskA()
    {
        return 123456;
    }

    static int TaskB(int val)
    {
        return val + 1;
    }

    static void Function()
    {

    }
    static void Function(object args)
    {

    }
    static int GetResult()
    {
        return 10086;
    }
}
赞(0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址