多线程 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);
            }

        }
原文地址:https://www.cnblogs.com/zhayunjia/p/4688931.html