zoukankan      html  css  js  c++  java
  • 多线程 thread和Task的用法以及注意事项

    并行 多核线程:Task

    首先引用System.Threading;

    1:用静态方法:Task.Factory.StartNew()来创建了一个最简单的Task:

    Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Hello World");
                });

    2:多种方法创建:

    using System.Threading.Tasks;
    namespace Listing_02
    {
        class Listing_02
        {
            static void Main(string[] args)
            {

          Task t = new Task(new Action(write));
          Task t = new Task(delegate { Console.WriteLine("a"); });
          Task t = new Task(() => { Console.WriteLine("a"); });
          Task t = new Task(() => { write(); });
          Task t = new Task(delegate(){ write(); });
          t.Start();
          Console.ReadLine();
          }
          private static void write()
          {
            Console.WriteLine("aynm");
          }

        }
    }

    3:为创建的Task传入参数

    using System;
    using System.Threading.Tasks;
    namespace Listing_04
    {
        class Listing_04
        {
            static void Main(string[] args)
            {
                string[] messages = { "First task", "Second task",
    "Third task", "Fourth task" };
                foreach (string msg in messages)
                {
                    Task myTask = new Task(obj => printMessage((string)obj), msg);
                    myTask.Start();
                }
                // wait for input before exiting
                Console.WriteLine("Main method complete. Press enter to finish.");
                Console.ReadLine();
            }
    
            static void printMessage(string message)
            {
                Console.WriteLine("Message: {0}", message);
            }
        }
    }

    注意:我们在传入参数后,必须把参数转换为它们原来的类型,然后再去调用相应的方法。例子中,因为System.Action对应的方法是printMessage()方法,而这个方法的要求的参数类型是string,所以要转换为string。

      想向Task传入参素,只能用System.Action<object>

    注意:

    foreach (string msg in messages) {
                Task MyTask = new Task(() => {
                    printMessage(msg);
                });
                MyTask.Start();
            }

    这样写是不正确的,这样会导致延迟加载,得不到预期的结果。

     原因:因为旧版本对“闭包”变量的处理 导致这样。

    可以这样改:

    
    
    foreach (string msg in messages)
    {
    string a = msg; 
    Task myTask
    = new Task(() => { printMessage(a); });
    MyTask.Start();
    }

     带参数的线程中  比如ParameterizedThreadStart可以传一个带参数的变量到线程所调用的方法。注意:方法传入的参数的变量类型元型是object类型的 所以在方法中必须对此类型进行类型显示处理 才能用:

    new Thread(new ParameterizedThreadStart(p.go)) { Name="线程1"}.Start(1000);
    
    private void go(object obj)
            {
                int time = Convert.ToInt16(obj);
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(Thread.CurrentThread.Name+" "+i.ToString());
                    Thread.Sleep(time);
                }
    
            }
  • 相关阅读:
    JS运算符
    JS基础
    0507-弹性盒子
    0506css3(2D、3D)动画
    CSS3边框
    0503-格式与布局
    0502-边框边界
    0502-其他html标签
    0428-专题块状元素
    mysql 数据库学习
  • 原文地址:https://www.cnblogs.com/zhayunjia/p/4688931.html
Copyright © 2011-2022 走看看